mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-02 05:12:02 +00:00
[client] overlay: show layout-translated hotkey labels
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Related to #1298
This commit is contained in:
@@ -225,6 +225,20 @@ done:
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool waylandGetKeyLabel(int key, char * label, size_t size)
|
||||||
|
{
|
||||||
|
if (!wlWm.xkbState)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
key += 8; // xkb scancode is evdev scancode + 8
|
||||||
|
xkb_keysym_t sym = xkb_state_key_get_one_sym(wlWm.xkbState, key);
|
||||||
|
sym = xkb_keysym_to_upper(sym);
|
||||||
|
|
||||||
|
const uint32_t codepoint = xkb_keysym_to_utf32(sym);
|
||||||
|
return codepoint > 0x20 && codepoint != 0x7F &&
|
||||||
|
xkb_keysym_to_utf8(sym, label, size) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void keyboardEnterHandler(void * data, struct wl_keyboard * keyboard,
|
static void keyboardEnterHandler(void * data, struct wl_keyboard * keyboard,
|
||||||
uint32_t serial, struct wl_surface * surface, struct wl_array * keys)
|
uint32_t serial, struct wl_surface * surface, struct wl_array * keys)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -320,6 +320,7 @@ struct LG_DisplayServerOps LGDS_Wayland =
|
|||||||
.uncapturePointer = waylandUncapturePointer,
|
.uncapturePointer = waylandUncapturePointer,
|
||||||
.grabKeyboard = waylandGrabKeyboard,
|
.grabKeyboard = waylandGrabKeyboard,
|
||||||
.ungrabKeyboard = waylandUngrabKeyboard,
|
.ungrabKeyboard = waylandUngrabKeyboard,
|
||||||
|
.getKeyLabel = waylandGetKeyLabel,
|
||||||
.warpPointer = waylandWarpPointer,
|
.warpPointer = waylandWarpPointer,
|
||||||
.realignPointer = waylandRealignPointer,
|
.realignPointer = waylandRealignPointer,
|
||||||
.isValidPointerPos = waylandIsValidPointerPos,
|
.isValidPointerPos = waylandIsValidPointerPos,
|
||||||
|
|||||||
@@ -378,6 +378,7 @@ void waylandUncapturePointer(void);
|
|||||||
void waylandRealignPointer(void);
|
void waylandRealignPointer(void);
|
||||||
void waylandWarpPointer(int x, int y, bool exiting);
|
void waylandWarpPointer(int x, int y, bool exiting);
|
||||||
void waylandGuestPointerUpdated(double x, double y, double localX, double localY);
|
void waylandGuestPointerUpdated(double x, double y, double localX, double localY);
|
||||||
|
bool waylandGetKeyLabel(int key, char * label, size_t size);
|
||||||
// output module
|
// output module
|
||||||
bool waylandOutputInit(void);
|
bool waylandOutputInit(void);
|
||||||
void waylandOutputFree(void);
|
void waylandOutputFree(void);
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
#include <X11/extensions/Xpresent.h>
|
#include <X11/extensions/Xpresent.h>
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
#include <GL/glxext.h>
|
#include <GL/glxext.h>
|
||||||
@@ -88,6 +91,7 @@ static void x11SetFullscreen(bool fs);
|
|||||||
static int x11EventThread(void * unused);
|
static int x11EventThread(void * unused);
|
||||||
static void x11XInputEvent(XGenericEventCookie *cookie);
|
static void x11XInputEvent(XGenericEventCookie *cookie);
|
||||||
static void x11XPresentEvent(XGenericEventCookie *cookie);
|
static void x11XPresentEvent(XGenericEventCookie *cookie);
|
||||||
|
static void x11UpdateKeyboardGroup(void);
|
||||||
static void x11GrabPointer(void);
|
static void x11GrabPointer(void);
|
||||||
|
|
||||||
static void x11DoPresent(uint64_t msc)
|
static void x11DoPresent(uint64_t msc)
|
||||||
@@ -568,8 +572,8 @@ static bool x11Init(const LG_DSInitParams params)
|
|||||||
goto fail_window;
|
goto fail_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxKeycode;
|
XDisplayKeycodes(x11.display, &x11.minKeycode, &x11.maxKeycode);
|
||||||
XDisplayKeycodes(x11.display, &x11.minKeycode, &maxKeycode);
|
x11UpdateKeyboardGroup();
|
||||||
|
|
||||||
XIFreeDeviceInfo(devinfo);
|
XIFreeDeviceInfo(devinfo);
|
||||||
|
|
||||||
@@ -1076,16 +1080,41 @@ static void updateModifiers(void)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void x11UpdateKeyboardGroup(void)
|
||||||
|
{
|
||||||
|
XkbStateRec state;
|
||||||
|
if (XkbGetState(x11.display, XkbUseCoreKbd, &state) == Success)
|
||||||
|
atomic_store(&x11.keyboardGroup, state.group);
|
||||||
|
}
|
||||||
|
|
||||||
static void setFocus(bool focused, double x, double y)
|
static void setFocus(bool focused, double x, double y)
|
||||||
{
|
{
|
||||||
if (x11.focused == focused)
|
if (x11.focused == focused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (focused)
|
||||||
|
x11UpdateKeyboardGroup();
|
||||||
|
|
||||||
x11.focused = focused;
|
x11.focused = focused;
|
||||||
app_updateCursorPos(x, y);
|
app_updateCursorPos(x, y);
|
||||||
app_handleFocusEvent(focused);
|
app_handleFocusEvent(focused);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool x11GetKeyLabel(int sc, char * label, size_t size)
|
||||||
|
{
|
||||||
|
const int keycode = sc + x11.minKeycode;
|
||||||
|
if (keycode < x11.minKeycode || keycode > x11.maxKeycode)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
xkb_keysym_t sym = XkbKeycodeToKeysym(
|
||||||
|
x11.display, keycode, atomic_load(&x11.keyboardGroup), 0);
|
||||||
|
sym = xkb_keysym_to_upper(sym);
|
||||||
|
|
||||||
|
const uint32_t codepoint = xkb_keysym_to_utf32(sym);
|
||||||
|
return codepoint > 0x20 && codepoint != 0x7F &&
|
||||||
|
xkb_keysym_to_utf8(sym, label, size) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void x11XInputEvent(XGenericEventCookie *cookie)
|
static void x11XInputEvent(XGenericEventCookie *cookie)
|
||||||
{
|
{
|
||||||
static int button_state = 0;
|
static int button_state = 0;
|
||||||
@@ -1217,6 +1246,7 @@ static void x11XInputEvent(XGenericEventCookie *cookie)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
XIDeviceEvent *device = cookie->data;
|
XIDeviceEvent *device = cookie->data;
|
||||||
|
atomic_store(&x11.keyboardGroup, device->group.effective);
|
||||||
app_handleKeyPress(device->detail - x11.minKeycode);
|
app_handleKeyPress(device->detail - x11.minKeycode);
|
||||||
|
|
||||||
if (!x11.xic || !app_isOverlayMode())
|
if (!x11.xic || !app_isOverlayMode())
|
||||||
@@ -2001,6 +2031,7 @@ struct LG_DisplayServerOps LGDS_X11 =
|
|||||||
.ungrabPointer = x11UngrabPointer,
|
.ungrabPointer = x11UngrabPointer,
|
||||||
.capturePointer = x11CapturePointer,
|
.capturePointer = x11CapturePointer,
|
||||||
.uncapturePointer = x11UncapturePointer,
|
.uncapturePointer = x11UncapturePointer,
|
||||||
|
.getKeyLabel = x11GetKeyLabel,
|
||||||
.grabKeyboard = x11GrabKeyboard,
|
.grabKeyboard = x11GrabKeyboard,
|
||||||
.ungrabKeyboard = x11UngrabKeyboard,
|
.ungrabKeyboard = x11UngrabKeyboard,
|
||||||
.warpPointer = x11WarpPointer,
|
.warpPointer = x11WarpPointer,
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ struct X11DSState
|
|||||||
XVisualInfo * visual;
|
XVisualInfo * visual;
|
||||||
X11WM * wm;
|
X11WM * wm;
|
||||||
|
|
||||||
int minKeycode;
|
int minKeycode, maxKeycode;
|
||||||
|
_Atomic(unsigned int) keyboardGroup;
|
||||||
|
|
||||||
//Extended Window Manager Hints
|
//Extended Window Manager Hints
|
||||||
//ref: https://specifications.freedesktop.org/wm-spec/latest/
|
//ref: https://specifications.freedesktop.org/wm-spec/latest/
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#define _H_I_DISPLAYSERVER_
|
#define _H_I_DISPLAYSERVER_
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
@@ -206,6 +207,9 @@ struct LG_DisplayServerOps
|
|||||||
void (*capturePointer)(void);
|
void (*capturePointer)(void);
|
||||||
void (*uncapturePointer)(void);
|
void (*uncapturePointer)(void);
|
||||||
|
|
||||||
|
/* get the active keymap's display label for the provided Linux keycode */
|
||||||
|
bool (*getKeyLabel)(int sc, char * label, size_t size);
|
||||||
|
|
||||||
/* exiting = true if the warp is to leave the window */
|
/* exiting = true if the warp is to leave the window */
|
||||||
void (*warpPointer)(int x, int y, bool exiting);
|
void (*warpPointer)(int x, int y, bool exiting);
|
||||||
|
|
||||||
@@ -283,6 +287,7 @@ struct LG_DisplayServerOps
|
|||||||
DEBUG_ASSERT((x)->ungrabPointer ); \
|
DEBUG_ASSERT((x)->ungrabPointer ); \
|
||||||
DEBUG_ASSERT((x)->capturePointer ); \
|
DEBUG_ASSERT((x)->capturePointer ); \
|
||||||
DEBUG_ASSERT((x)->uncapturePointer ); \
|
DEBUG_ASSERT((x)->uncapturePointer ); \
|
||||||
|
DEBUG_ASSERT((x)->getKeyLabel ); \
|
||||||
DEBUG_ASSERT((x)->warpPointer ); \
|
DEBUG_ASSERT((x)->warpPointer ); \
|
||||||
DEBUG_ASSERT((x)->realignPointer ); \
|
DEBUG_ASSERT((x)->realignPointer ); \
|
||||||
DEBUG_ASSERT((x)->isValidPointerPos ); \
|
DEBUG_ASSERT((x)->isValidPointerPos ); \
|
||||||
|
|||||||
@@ -56,7 +56,11 @@ static int help_render(void * udata, bool interactive, struct Rect * windowRects
|
|||||||
|
|
||||||
if (igBeginTable("Help", 2, 0, (ImVec2) { 0.0f, 0.0f }, 0.0f))
|
if (igBeginTable("Help", 2, 0, (ImVec2) { 0.0f, 0.0f }, 0.0f))
|
||||||
{
|
{
|
||||||
|
char escapeLabel[8];
|
||||||
const char * escapeName = linux_to_display[g_params.escapeKey];
|
const char * escapeName = linux_to_display[g_params.escapeKey];
|
||||||
|
if (g_state.ds->getKeyLabel(
|
||||||
|
g_params.escapeKey, escapeLabel, sizeof(escapeLabel)))
|
||||||
|
escapeName = escapeLabel;
|
||||||
|
|
||||||
igTableNextColumn();
|
igTableNextColumn();
|
||||||
igText("%s", escapeName);
|
igText("%s", escapeName);
|
||||||
@@ -69,8 +73,13 @@ static int help_render(void * udata, bool interactive, struct Rect * windowRects
|
|||||||
if (!handle->description)
|
if (!handle->description)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
char keyLabel[8];
|
||||||
|
const char * keyName = linux_to_display[handle->sc];
|
||||||
|
if (g_state.ds->getKeyLabel(handle->sc, keyLabel, sizeof(keyLabel)))
|
||||||
|
keyName = keyLabel;
|
||||||
|
|
||||||
igTableNextColumn();
|
igTableNextColumn();
|
||||||
igText("%s+%s", escapeName, linux_to_display[handle->sc]);
|
igText("%s+%s", escapeName, keyName);
|
||||||
igTableNextColumn();
|
igTableNextColumn();
|
||||||
igTextUnformatted(handle->description, NULL);
|
igTextUnformatted(handle->description, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user