Skip to content
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

Feature/Linux KDE Plasma Desktop environment support #37

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ It can be useful for example if you want to synchronize your GUI App's look and
> This library is inspired by the dark-theme detection in [Intellij Idea](https://github.com/JetBrains/intellij-community).

# Compatibility
It works on **Windows 10**, **MacOS Mojave** (or later) and even on **some Linux distributions**.
It works on **Windows 10**, **MacOS Mojave** (or later) and even on **some Linux desktop environments**:

- Gnome: Fully supported and tested on Ubuntu
- KDE Plasma: For now will only support `isDark` method, tested on Ubuntu with `kde-plasma-desktop` package

# Requirements
**Java 11 or higher**
Expand Down
98 changes: 98 additions & 0 deletions src/main/java/com/jthemedetecor/KdeThemeDetector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.jthemedetecor;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.function.Consumer;

/**
* Used for detecting the dark theme on a Linux KDE desktop environment.
* Tested on Ubuntu KDE Plasma (kde-plasma-desktop).
*
* @see GnomeThemeDetector
*/
public class KdeThemeDetector extends OsThemeDetector {
private static final Logger logger = LoggerFactory.getLogger(KdeThemeDetector.class);
/**
* List of the known look and feel packages, if the user use a package that is not listed in this list
* then will check if the package name contains `dark` regardless of the case sensitivity
* */
private static final String[] darkLookAndFeelPackages = {
"org.kde.breezedark.desktop", "org.kde.oxygen", "org.kde.arc-dark",
"org.kde.numix-dark", "org.kde.papirus-dark", "org.kde.suru-dark"
};

@Override
public boolean isDark() {
try {
String currentLookAndFeelPackageName = getCurrentLookAndFeelPackageName();

if (Arrays.asList(darkLookAndFeelPackages).contains(currentLookAndFeelPackageName)) {
return true;
}

return currentLookAndFeelPackageName.toLowerCase().contains("dark".toLowerCase());

} catch (IOException e) {
logger.error("Couldn't detect Linux OS theme", e);
return false;
}
}

private String getCurrentLookAndFeelPackageName() throws IOException {
String kdeGlobalsFilePath;

// Get user's home directory
Path homeDir = Paths.get(System.getProperty("user.home"));

// Build the complete file path
kdeGlobalsFilePath = homeDir.resolve(".config/kdeglobals").toString();

// Read the file and get the value of the property LookAndFeelPackage
try (BufferedReader reader = new BufferedReader(new FileReader(kdeGlobalsFilePath))) {
String lookAndFeelPackage = null;
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("LookAndFeelPackage=")) {
lookAndFeelPackage = line.substring(line.indexOf("=") + 1);
break;
}
}
return lookAndFeelPackage;
}
}

// TODO: Add support for the listeners, don't forgot to update the README.md if you did

@Override
public synchronized void registerListener(@NotNull Consumer<Boolean> darkThemeListener) {

}

@Override
public synchronized void removeListener(@Nullable Consumer<Boolean> darkThemeListener) {

}
}
6 changes: 5 additions & 1 deletion src/main/java/com/jthemedetecor/OsThemeDetector.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ private static OsThemeDetector createDetector() {
} else if (OsInfo.isGnome()) {
logDetection("Gnome", GnomeThemeDetector.class);
return new GnomeThemeDetector();
} else if (OsInfo.isKde()) {
logDetection("Kde", KdeThemeDetector.class);
return new KdeThemeDetector();
} else if (OsInfo.isMacOsMojaveOrLater()) {
logDetection("MacOS", MacOSThemeDetector.class);
return new MacOSThemeDetector();
Expand Down Expand Up @@ -102,7 +105,8 @@ private static void logDetection(String desktop, Class<? extends OsThemeDetector

@ThreadSafe
public static boolean isSupported() {
return OsInfo.isWindows10OrLater() || OsInfo.isMacOsMojaveOrLater() || OsInfo.isGnome();
return OsInfo.isWindows10OrLater() || OsInfo.isMacOsMojaveOrLater() || OsInfo.isGnome() ||
OsInfo.isKde();
}

private static final class EmptyDetector extends OsThemeDetector {
Expand Down
15 changes: 10 additions & 5 deletions src/main/java/com/jthemedetecor/util/OsInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,17 @@ public static boolean isMacOsMojaveOrLater() {
return hasTypeAndVersionOrHigher(PlatformEnum.MACOS, "10.14");
}

@NotNull
public static String getCurrentLinuxDesktopEnvironmentName() {
return System.getenv("XDG_CURRENT_DESKTOP");
}

public static boolean isGnome() {
return isLinux() && (
queryResultContains("echo $XDG_CURRENT_DESKTOP", "gnome") ||
queryResultContains("echo $XDG_DATA_DIRS | grep -Eo 'gnome'", "gnome") ||
queryResultContains("ps -e | grep -E -i \"gnome\"", "gnome")
);
return isLinux() && getCurrentLinuxDesktopEnvironmentName().toLowerCase().contains("gnome");
}

public static boolean isKde() {
return isLinux() && getCurrentLinuxDesktopEnvironmentName().toLowerCase().contains("KDE".toLowerCase());
}

public static boolean hasType(PlatformEnum platformType) {
Expand Down