feat: add keyboard layout support

This commit is contained in:
2026-08-13 17:57:44 +02:00
parent 86e3ebfe33
commit 821543238d
36 changed files with 1132 additions and 125 deletions
+56 -14
View File
@@ -7,6 +7,27 @@
#include "desktop_internal.hpp"
#include <montauk/user.h>
bool gui::desktop_refresh_keyboard_layouts(DesktopState* ds, bool force) {
if (!ds) return false;
uint64_t now = montauk::get_milliseconds();
if (!force && now - ds->keyboard_last_poll < 1000) return false;
// Only the selection can change while we run: the layout tables are
// read-only OS data, so there is no reason to re-parse them every second.
int prev_active = ds->keyboard.active;
bool prev_enabled[montauk::keyboard::MAX_LAYOUTS];
for (int i = 0; i < montauk::keyboard::MAX_LAYOUTS; i++)
prev_enabled[i] = ds->keyboard.enabled[i];
montauk::keyboard::refresh_selection(&ds->keyboard, ds->current_user);
bool changed = ds->keyboard.active != prev_active;
for (int i = 0; !changed && i < ds->keyboard.registry.count; i++)
changed = ds->keyboard.enabled[i] != prev_enabled[i];
ds->keyboard_last_poll = now;
return changed;
}
static bool try_unlock(DesktopState* ds) {
ds->lock_show_error = false;
@@ -85,7 +106,8 @@ static void handle_lock_keyboard(DesktopState* ds, const montauk::abi::KeyEvent&
}
// Printable characters
if (key.ascii >= 0x20 && key.ascii < 0x7F) {
if ((unsigned char)key.ascii >= 0x20
&& (unsigned char)key.ascii != 0x7F) {
if (ds->lock_password_len < 63) {
ds->lock_password[ds->lock_password_len] = key.ascii;
ds->lock_password_len++;
@@ -538,6 +560,22 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
return;
}
// Keyboard layout indicator: cycle through the layouts enabled in the
// Keyboard Settings applet and persist the new active choice.
if (ds->keyboard_layout_rect.w > 0
&& ds->keyboard_layout_rect.contains(mx, my)) {
ds->keyboard.active = montauk::keyboard::next_enabled(
ds->keyboard, ds->keyboard.active);
montauk::keyboard::save_user(ds->current_user, ds->keyboard);
ds->keyboard_last_poll = montauk::get_milliseconds();
ds->app_menu_open = false;
ds->net_popup_open = false;
ds->wifi_popup_open = false;
ds->vol_popup_open = false;
gui::mtk::context_menu_close(ds->ctx_menu);
return;
}
// Volume icon
if (ds->vol_icon_rect.w > 0 && ds->vol_icon_rect.contains(mx, my)) {
ds->vol_popup_open = !ds->vol_popup_open;
@@ -801,8 +839,12 @@ void gui::desktop_handle_mouse(DesktopState* ds) {
}
void gui::desktop_handle_keyboard(DesktopState* ds, const montauk::abi::KeyEvent& key) {
montauk::abi::KeyEvent translated_key = key;
montauk::keyboard::translate(ds->keyboard, &translated_key);
const montauk::abi::KeyEvent& routed_key = translated_key;
if (ds->screen_locked) {
handle_lock_keyboard(ds, key);
handle_lock_keyboard(ds, routed_key);
return;
}
@@ -816,7 +858,7 @@ void gui::desktop_handle_keyboard(DesktopState* ds, const montauk::abi::KeyEvent
montauk::abi::WinEvent ev;
montauk::memset(&ev, 0, sizeof(ev));
ev.type = 0; // key
ev.key = key;
ev.key = routed_key;
montauk::win_sendevent(win->ext_win_id, &ev);
ds->launcher_open = false;
ds->app_menu_open = false;
@@ -824,37 +866,37 @@ void gui::desktop_handle_keyboard(DesktopState* ds, const montauk::abi::KeyEvent
return;
}
if (desktop_handle_launcher_keyboard(ds, key)) {
if (desktop_handle_launcher_keyboard(ds, routed_key)) {
return;
}
// Global shortcuts (only on key press)
if (key.pressed && key.ctrl && key.alt) {
if (key.ascii == 'l' || key.ascii == 'L') {
if (routed_key.pressed && routed_key.ctrl && routed_key.alt) {
if (routed_key.ascii == 'l' || routed_key.ascii == 'L') {
desktop_lock_screen(ds);
return;
}
if (key.ascii == 't' || key.ascii == 'T') {
if (routed_key.ascii == 't' || routed_key.ascii == 'T') {
open_terminal(ds);
return;
}
if (key.ascii == 'f' || key.ascii == 'F') {
if (routed_key.ascii == 'f' || routed_key.ascii == 'F') {
open_filemanager(ds);
return;
}
if (key.ascii == 'c' || key.ascii == 'C') {
if (routed_key.ascii == 'c' || routed_key.ascii == 'C') {
open_calculator(ds);
return;
}
if (key.ascii == 'e' || key.ascii == 'E') {
if (routed_key.ascii == 'e' || routed_key.ascii == 'E') {
open_texteditor(ds);
return;
}
if (key.ascii == 'w' || key.ascii == 'W') {
if (routed_key.ascii == 'w' || routed_key.ascii == 'W') {
open_wordprocessor(ds);
return;
}
if (key.ascii == 'k' || key.ascii == 'K') {
if (routed_key.ascii == 'k' || routed_key.ascii == 'K') {
open_klog(ds);
return;
}
@@ -868,10 +910,10 @@ void gui::desktop_handle_keyboard(DesktopState* ds, const montauk::abi::KeyEvent
montauk::abi::WinEvent ev;
montauk::memset(&ev, 0, sizeof(ev));
ev.type = 0; // key
ev.key = key;
ev.key = routed_key;
montauk::win_sendevent(win->ext_win_id, &ev);
} else if (win->on_key) {
win->on_key(win, key);
win->on_key(win, routed_key);
}
}
}