diff --git a/src/main/java/com/rdesk/Main.java b/src/main/java/com/rdesk/Main.java index 12a8402..7927f29 100644 --- a/src/main/java/com/rdesk/Main.java +++ b/src/main/java/com/rdesk/Main.java @@ -16,9 +16,10 @@ import javax.swing.*; public class Main { - private static final boolean RUN_IN_FS = true; + private static final boolean RUN_IN_FS = false; private static final boolean USE_SYSDEFAULT_LAF = false; private static final boolean USE_FLATLAF = false; + private static final boolean loadSettingsKernelFlag = true; public static void main(String[] args) { SwingUtilities.invokeLater(Main::boot); @@ -26,6 +27,7 @@ public class Main { private static void boot() { Kernel kernel = Kernel.get(); + kernel.initSettings(loadSettingsKernelFlag); kernel.boot(); JFrame frame = new JFrame("rDesk"); diff --git a/src/main/java/com/rdesk/applications/system/rsys/KbChanger.java b/src/main/java/com/rdesk/applications/system/rsys/KbChanger.java index 4226c92..5d2d510 100644 --- a/src/main/java/com/rdesk/applications/system/rsys/KbChanger.java +++ b/src/main/java/com/rdesk/applications/system/rsys/KbChanger.java @@ -1,5 +1,7 @@ package com.rdesk.applications.system.rsys; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.rdesk.kernel.DesktopApp; import com.rdesk.kernel.Kernel; import com.rdesk.kernel.rsys.KbInterface; @@ -9,6 +11,10 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.io.Reader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; public class KbChanger implements DesktopApp { private static final String[] LAYOUTS = { @@ -66,6 +72,24 @@ public class KbChanger implements DesktopApp { KbInterface kb = new KbInterface(); + try { + Path configPath = Paths.get(System.getProperty("user.home"), "rsys", "rsys_kblayout.json"); + if (Files.exists(configPath)) { + try (Reader reader = Files.newBufferedReader(configPath)) { + JsonObject config = JsonParser.parseReader(reader).getAsJsonObject(); + if (config.has("kblayout")) { + String savedLayout = config.get("kblayout").getAsString(); + layoutCombo.setSelectedItem(savedLayout); + status.setText("Last applied: " + savedLayout); + + kb.setKbLayout(savedLayout); + } + } + } + } catch (Exception ex) { + System.err.println("Failed to read existing kb layout config: " + ex.getMessage()); + } + applyBtn.addActionListener((ActionEvent e) -> { String selected = (String) layoutCombo.getSelectedItem(); if (selected == null || selected.trim().isEmpty()) { @@ -74,6 +98,7 @@ public class KbChanger implements DesktopApp { } kb.setKbLayout(selected); + kb.saveLayout(selected); status.setText("Last applied: " + selected); SwingUtilities.invokeLater(testField::requestFocusInWindow); @@ -91,4 +116,4 @@ public class KbChanger implements DesktopApp { frame.setVisible(true); return frame; } -} +} \ No newline at end of file diff --git a/src/main/java/com/rdesk/kernel/Kernel.java b/src/main/java/com/rdesk/kernel/Kernel.java index d83b7ed..b50d3e2 100644 --- a/src/main/java/com/rdesk/kernel/Kernel.java +++ b/src/main/java/com/rdesk/kernel/Kernel.java @@ -1,11 +1,17 @@ package com.rdesk.kernel; +import com.rdesk.kernel.launcher.AppLauncher; +import com.rdesk.kernel.rsys.KbInterface; + import javax.swing.*; public class Kernel { private static volatile Kernel instance; + // set to true in production builds + private boolean initSettings = true; + private final AppManager appManager; private final WindowManager windowManager; private final EventBus eventBus; @@ -35,8 +41,23 @@ public class Kernel { public void boot() { running = true; - System.out.println("[Kernel] Booting..."); + kInfo("Booting"); eventBus.emit("kernel.boot"); + // load keyboard layout: + if (initSettings) + initRSysSettings(); + } + + + private void initRSysSettings() { + try { + kInfo("loading system config for : " + (String) System.getProperty("os.name")); + KbInterface kbInterface = new KbInterface(); + kbInterface.loadLayout(); + kInfo("loaded kbLayout"); + } catch (Exception e) { + kErr("Failed to initialize system settings ; error message: " + e.getMessage()); + } } public void attachFrame(JFrame frame) { @@ -46,7 +67,7 @@ public class Kernel { public void shutdown() { if (!running) return; - System.out.println("[Kernel] Shutdown started"); + kInfo("Shutting down"); running = false; appManager.stopAll(); @@ -57,10 +78,16 @@ public class Kernel { } eventBus.emit("kernel.shutdown"); - System.out.println("[Kernel] Shutdown complete"); + kInfo("Shut down Kernel"); System.exit(0); } + // kernel info string printers + private void kErr(String errmsg) { System.err.println("[KERNEL FAULT]: " + errmsg); } + private void kInfo(String infomsg) { System.out.println("[Kernel]: " + infomsg); } + + // public kernel api + public void initSettings(boolean flag) { initSettings = flag; } public AppManager apps() { return appManager; } public WindowManager windows() { return windowManager; } public EventBus events() { return eventBus; } diff --git a/src/main/java/com/rdesk/kernel/rsys/KbInterface.java b/src/main/java/com/rdesk/kernel/rsys/KbInterface.java index 9a1208c..161c292 100644 --- a/src/main/java/com/rdesk/kernel/rsys/KbInterface.java +++ b/src/main/java/com/rdesk/kernel/rsys/KbInterface.java @@ -1,50 +1,77 @@ - package com.rdesk.kernel.rsys; -import com.sun.jna.Library; -import com.sun.jna.Native; -import com.sun.jna.win32.W32APIOptions; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import javax.swing.*; +import java.io.Reader; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; public class KbInterface { + /* DISCLAIMER: + * This is a class which is though to be for the rsys operating system, + * it only supports the keyboard set option for x11, macos and windows isnt supported + */ + private static class KbConfig { + String kblayout; - private static final java.util.Map LAYOUT_TO_KLID = java.util.Map.ofEntries( - java.util.Map.entry("us", "00000409"), - java.util.Map.entry("uk", "00000809"), - java.util.Map.entry("de", "00000407"), - java.util.Map.entry("fr", "0000040C"), - java.util.Map.entry("es", "0000040A"), - java.util.Map.entry("it", "00000410"), - java.util.Map.entry("ru", "00000419"), - java.util.Map.entry("jp", "00000411"), - java.util.Map.entry("br", "00000416"), - java.util.Map.entry("cz", "00000405") - ); - - - private interface User32 extends Library { - User32 INSTANCE = Native.load("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS); - long LoadKeyboardLayoutA(String pwszKLID, int Flags); + public KbConfig(String kblayout) { + this.kblayout = kblayout; + } } + private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + public void setKbLayout(String kbLayout) { String os = System.getProperty("os.name").toLowerCase(); try { - if (os.contains("win")) { - setWindowsLayout(kbLayout); - } else if (os.contains("nix") || os.contains("nux") || os.contains("aix") || os.contains("linux")) { - setLinuxLayout(kbLayout); + if (os.contains("nix") || os.contains("nux") || os.contains("aix") || os.contains("linux")) { + setLinuxLayout(kbLayout); // actual work! } else if (os.contains("mac")) { - showError("mac is too shitty for this"); + logErr("mac is too shitty for this"); } else { - showError("what are you running?: " + os); + logErr("what are you running?: " + os); } } catch (Exception ex) { showError("The keyboard layout could not be set " + ex.getMessage()); } } + public void loadLayout() { + Path configPath = getConfigPath(); + if (!Files.exists(configPath)) { + return; + } + + try (Reader reader = Files.newBufferedReader(configPath)) { + KbConfig config = gson.fromJson(reader, KbConfig.class); + if (config != null && config.kblayout != null && !config.kblayout.isBlank()) { + setKbLayout(config.kblayout); + } + } catch (Exception ex) { + logErr("Failed to load layout configuration: " + ex.getMessage()); + } + } + + public void saveLayout(String kbLayout) { + Path configPath = getConfigPath(); + try { + Files.createDirectories(configPath.getParent()); + try (Writer writer = Files.newBufferedWriter(configPath)) { + gson.toJson(new KbConfig(kbLayout), writer); + } + } catch (Exception ex) { + logErr("Failed to save layout configuration: " + ex.getMessage()); + } + } + + private Path getConfigPath() { + return Paths.get(System.getProperty("user.home"), "rsys", "rsys_kblayout.json"); + } + private void setLinuxLayout(String kbLayout) throws Exception { new ProcessBuilder("setxkbmap", kbLayout) .inheritIO() @@ -52,22 +79,7 @@ public class KbInterface { .waitFor(); } - private void setWindowsLayout(String kbLayout) { - String klid = kbLayout; - if (!kbLayout.matches("[0-9A-Fa-f]{8}")) { - klid = LAYOUT_TO_KLID.getOrDefault(kbLayout.toLowerCase(), null); - if (klid == null) { - showError("Unknown Windows layout: " + kbLayout); - return; - } - } - - int KLF_ACTIVATE = 0x00000001; - long result = User32.INSTANCE.LoadKeyboardLayoutA(klid, KLF_ACTIVATE); - if (result == 0) { - showError("Failed to load keyboard layout " + klid); - } - } + private void logErr(String message) { System.err.println("[KbInterface.java]: " + (String) message); } private void showError(String message) { JOptionPane.showMessageDialog( @@ -77,4 +89,4 @@ public class KbInterface { JOptionPane.ERROR_MESSAGE ); } -} +} \ No newline at end of file