-
-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for color-scheme preference on Linux #51
Conversation
I wasn't able to run it yet, it always hangs while processing resources and compiling Kotlin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few comments. I'm not sure why it's spinning on prepareResources
for you though. What command are you using for building? Also this doesn't seem to actually implement detecting changes to the org.freedesktop.appearance/color-scheme
. Will this be added?
...dg-desktop-portal/src/main/java/com/github/weisj/darkmode/platform/linux/xdg/XdgLibrary.java
Outdated
Show resolved
Hide resolved
I can implement detecting changes, there is a signal for that. For now, I just wanted basic functionality and worry about that once I know the concept works. To test the implementation, I wrote a test under .../xdg-desktop-portal/src/test/... and run it using the green arrow that IDEA shows next to the test. I also tried to write scratch files, but that didn't work either. Please let me know if there is a better way 😅 |
d1eba40
to
a98ae0c
Compare
You'll have to setup the gradle project to use junit. depenencies {
...
testImplementation(libs.test.junit.api)
testRuntimeOnly(libs.test.junit.engine)
}
tasks {
test {
testLogging {
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
showStandardStreams = true
}
useJUnitPlatform()
}
} IntelliJ should automatically pick up the gradel task to run tests. If not use If you run into the build spinning on |
Thanks a lot, its now working! I now have some questions on the implementation:
|
ae92e2e
to
e84ad15
Compare
In this case it should just return the current state i.e. not result in a change at all.
Please simply return |
I have some issues implementing the event handling. I guess val callback = eventHandle.castSafelyTo<() -> Unit>() However, I couldn't find a way to cast a callable to a native pointer... Another thing I couldn't find was a way to return the currently used theme mode of the IDE. Is there a boolean that stores the current theme mode, or can I check if the currently used theme is dark? |
The contract of the class is that
Because it isn't possible ;)
There are two options here. Either keep track of the current state yourself and return it, or change the type of callback from data class ThemeInfo(val isDark, val isHighContrast) You'll have to adjust the interface of |
I looked a bit deeper through the code and I found that if |
linux/xdg/src/main/java/com/github/weisj/darkmode/platform/linux/xdg/FreedesktopInterface.kt
Outdated
Show resolved
Hide resolved
linux/xdg/src/main/java/com/github/weisj/darkmode/platform/linux/xdg/XdgThemeMonitorService.kt
Outdated
Show resolved
Hide resolved
linux/xdg/src/main/java/com/github/weisj/darkmode/platform/linux/xdg/XdgThemeMonitorService.kt
Outdated
Show resolved
Hide resolved
linux/xdg/src/main/java/com/github/weisj/darkmode/platform/linux/xdg/XdgThemeMonitorService.kt
Outdated
Show resolved
Hide resolved
linux/xdg/src/main/java/com/github/weisj/darkmode/platform/linux/xdg/XdgThemeMonitorService.kt
Outdated
Show resolved
Hide resolved
I ran into a similar issue and the solution for me was to disable parallel builds, in |
840e498
to
42e3fe6
Compare
|
linux/xdg/src/main/java/com/github/weisj/darkmode/platform/linux/xdg/FreedesktopInterface.kt
Outdated
Show resolved
Hide resolved
linux/src/main/java/com/github/weisj/darkmode/platform/linux/LinuxThemeMonitorService.kt
Outdated
Show resolved
Hide resolved
There seems to be a deadlock somewhere, when I run the IDE it spins endlessly (at task Any suggestions? 😅 Debug Log... 2022-05-12T18:10:35.399+0200 [DEBUG] [org.jetbrains.intellij.IntelliJPlugin] [gradle-intellij-plugin :auto-dark-mode-pluginauto-dark-mode-plugin:auto-dark-mode-plugin:runIde] Runtime specified with ideDir='/home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2022.1/c91a19824ffcb28872ecd2761c83b250f703ff21/ideaIC-2022.1', version='11_0_14_1b2043.25' resolved as: /home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains/jbre/jbr_jcef-11_0_14_1-linux-x64-b2043.25/extracted/jbr/bin/java 2022-05-12T18:10:35.399+0200 [INFO] [org.jetbrains.intellij.IntelliJPlugin] [gradle-intellij-plugin :auto-dark-mode-pluginauto-dark-mode-plugin:auto-dark-mode-plugin:runIde] Resolved JVM Runtime directory: /home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains/jbre/jbr_jcef-11_0_14_1-linux-x64-b2043.25/extracted/jbr/bin/java 2022-05-12T18:10:35.399+0200 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'command '/home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains/jbre/jbr_jcef-11_0_14_1-linux-x64-b2043.25/extracted/jbr/bin/java''. Working directory: /home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2022.1/c91a19824ffcb28872ecd2761c83b250f703ff21/ideaIC-2022.1/bin Command: /home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains/jbre/jbr_jcef-11_0_14_1-linux-x64-b2043.25/extracted/jbr/bin/java -Didea.auto.reload.plugins=true -Didea.classpath.index.enabled=false -Didea.config.path=/home/l0drex/Projekte/auto-dark-mode/plugin/build/idea-sandbox/config -Didea.is.internal=true -Didea.platform.prefix=Idea -Didea.plugins.path=/home/l0drex/Projekte/auto-dark-mode/plugin/build/idea-sandbox/plugins -Didea.required.plugins.id=com.github.weisj.darkmode -Didea.system.path=/home/l0drex/Projekte/auto-dark-mode/plugin/build/idea-sandbox/system -Djava.system.class.loader=com.intellij.util.lang.PathClassLoader -Dsun.awt.disablegrab=true -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country=DE -Duser.language=de -Duser.variant -ea -cp /home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2022.1/c91a19824ffcb28872ecd2761c83b250f703ff21/ideaIC-2022.1/lib/3rd-party-rt.jar:/home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2022.1/c91a19824ffcb28872ecd2761c83b250f703ff21/ideaIC-2022.1/lib/util.jar:/home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2022.1/c91a19824ffcb28872ecd2761c83b250f703ff21/ideaIC-2022.1/lib/util_rt.jar:/home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2022.1/c91a19824ffcb28872ecd2761c83b250f703ff21/ideaIC-2022.1/lib/jna.jar com.intellij.idea.Main 2022-05-12T18:10:35.399+0200 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Changing state to: STARTING 2022-05-12T18:10:35.399+0200 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Waiting until process started: command '/home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains/jbre/jbr_jcef-11_0_14_1-linux-x64-b2043.25/extracted/jbr/bin/java'. 2022-05-12T18:10:35.400+0200 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Changing state to: STARTED 2022-05-12T18:10:35.400+0200 [DEBUG] [org.gradle.process.internal.ExecHandleRunner] waiting until streams are handled... 2022-05-12T18:10:35.400+0200 [INFO] [org.gradle.process.internal.DefaultExecHandle] Successfully started process 'command '/home/l0drex/.gradle/caches/modules-2/files-2.1/com.jetbrains/jbre/jbr_jcef-11_0_14_1-linux-x64-b2043.25/extracted/jbr/bin/java'' 2022-05-12T18:10:35.520+0200 [ERROR] [system.err] WARNING: An illegal reflective access operation has occurred An illegal reflective access operation has occurred |
Have you tried commenting out the code which creates the XdgThemeMonitorService? |
Yes, when I do that it works. private val connection = DBusConnection.getConnection(DBusConnection.DBusBusType.SESSION) I don't know why yet, but I did found another plugin that uses the dbus so that in itself shouldn't be a problem. |
private val freedesktopConnection = FreedesktopConnection() | ||
private val sigHandler = SigHandler() | ||
override val isDarkThemeEnabled: Boolean = freedesktopConnection.theme == ThemeMode.DARK | ||
override val isSupported: Boolean = freedesktopConnection.theme != ThemeMode.ERROR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try this. Calling out to system resources during class initialization makes debugging deadlocks rather difficult. This way you'll at least know which call is causing the lock (It might not be the creation of the connection but the theme
call instead)
private val freedesktopConnection = FreedesktopConnection() | |
private val sigHandler = SigHandler() | |
override val isDarkThemeEnabled: Boolean = freedesktopConnection.theme == ThemeMode.DARK | |
override val isSupported: Boolean = freedesktopConnection.theme != ThemeMode.ERROR | |
private val freedesktopConnection by lazy { FreedesktopConnection() } | |
private val sigHandler = SigHandler() | |
override val isDarkThemeEnabled: Boolean | |
get() = freedesktopConnection.theme == ThemeMode.DARK | |
override val isSupported: Boolean | |
get() = freedesktopConnection.theme != ThemeMode.ERROR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure it's the creation of the connection. When I comment everything out except the creation, the deadlock is still there 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can’t comment out isDarkThemeEnabled
and isSupported
though as they need to be implemented in order for the class to compile. Did you stub them or what exactly do you mean by commenting out?
Also it would be beneficial to add some unit tests, testing whether it works in isolation outside IntelliJ.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to run IDE and plugin without the sandbox?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can’t comment out isDarkThemeEnabled and isSupported though as they need to be implemented in order for the class to compile. Did you stub them or what exactly do you mean by commenting out?
Also, it would be beneficial to add some unit tests, testing whether it works in isolation outside IntelliJ.
Didn't see that, sorry 😅
I just returned true and commented the rest out. I have unittests that I run regularly, but I didn't commit them as I don't know which theme is actually active
I have now another weird problem. I wanted to update the Specifically, I need to change this: private val connection = DBusConnection.getConnection(DBusConnection.DBusBusType.SESSION) to this: private val connection = DBusConnectionBuilder.forSessionBus().build() This works when I test it in a new, empty project, but here it throws an error that I checked the dependency menu in the Gradle toolbar, it only shows the correct version of the library. I deleted all build directories, cache directories, |
Are you sure this is a gradle issue and not something with your IDE? i.e. does running |
Yes, it also happens when I run the build from the command line. Building with the dependency commented out didn't help, I even ran it on a different machine and have the same issue there. |
To keep you updated, I made a post in the developer forum of JetBrains to see if they can help me with that endless spinning on |
private val connection: DBusConnection? = try { | ||
// Temporarily replace the current tread's contextClassLoader to work around dbus-java's naive service loading | ||
val ccl = Thread.currentThread().contextClassLoader | ||
Thread.currentThread().contextClassLoader = javaClass.classLoader | ||
val conn = DBusConnectionBuilder.forSessionBus().build() | ||
Thread.currentThread().contextClassLoader = ccl | ||
conn | ||
} catch (_: DBusException) { | ||
null | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There already is a similar "hack" used in ServiceUtil.java. This should probably be extracted into a separate helper method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should that go into a new class, or is there a utility class where I could add that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There currently isn't a good place to put it. Feel free to create a separate utility class for it.
I would also highly appreciate if you could add some tests similar to https://github.com/weisJ/auto-dark-mode/blob/master/plugin/src/test/kotlin/com/github/weisj/darkmode/platform/linux/gtk/GtkNativeTest.kt. |
It seems like it is, it looks like its marked as a dependency in intellij-community |
I extracted the theme changer so that it can be used by other tests. I also added a theme changer for kde, however getting the currently used theme is not so straight forward. |
I'm not sure myself how to tackle this currently. I think it's ok to leave this as a FIXME for now, as it doesn't influence the tests that much beside the fact that we have to trust the theme being really changed (and if run locally the theme not being preserved for the developer) |
Tests are currently failing because there is no xserver running causing the test to be executed headless. I had a similar issue in one of my other projects and the following seemed to fix it: |
Sorry for not getting back any sooner. The test not being able to run is rather unfortunate, but I don't have a solution for that right now. I guess we would have to guarantee that the action runner actuallyhas a working dbus with the correct properties exposed. For now I'll disable the test and provide the patch as an optional preview-version. |
7d1161e
to
4f4add5
Compare
Some systems (notably WSL distros) don't ship with a xsettings daemon. Also check the old setting to ensure we don't miss any changes.
36fb7ce
to
5d76773
Compare
Linux support for all desktops that implement the
color-scheme
preference. Implementation is based on this gist.First time using Gradle and Kotlin, any help is welcome 😄
Fix #56
Fix #50
Fix #33
Fix #20