feat: add keyboard layout support
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user