arch: usermenu key send through vtable; drop dead misc.c code
* usermenu.c notifyClient: replace XSendEvent KeyPress/KeyRelease
synthesis with two wm_backend->client_send_key calls.
* New vtable slot client_send_key(win, keycode, modifier_mask, press).
X11: synthesize XKeyEvent and XSendEvent.
Wayland: same but on wl_state.x_display (XWayland clients). Native
Wayland clients deferred (would need
zwp_virtual_keyboard_v1).
* misc.c: keysymToString was dead code inside #if 0 — removed.
After this change misc.c and usermenu.c carry zero direct Xlib calls.
This commit is contained in:
parent
9cca44c765
commit
60d71f46b4
|
|
@ -1794,6 +1794,20 @@ typedef struct WMBackend {
|
|||
int (*event_check_window)(WNativeWindow win, int event_type);
|
||||
int (*event_check_type)(int event_type, WMEvent *event_out);
|
||||
void (*client_send_event)(WNativeWindow win, void *event_data);
|
||||
|
||||
/*
|
||||
* Deliver a synthetic key press/release to a client window. Used by
|
||||
* usermenu.c to translate menu entries into keystrokes for the
|
||||
* focused client.
|
||||
*
|
||||
* X11: synthesize XKeyEvent and XSendEvent it to the window.
|
||||
* Wayland: deliver via XSendEvent for XWayland clients (the X
|
||||
* server backed by wlroots' xwayland surfaces still
|
||||
* accepts synthetic events). Native Wayland clients are
|
||||
* not yet handled (would need zwp_virtual_keyboard_v1).
|
||||
*/
|
||||
void (*client_send_key)(WNativeWindow win, unsigned int keycode,
|
||||
unsigned int modifier_mask, int press);
|
||||
int (*window_exists)(WNativeWindow win);
|
||||
void (*window_get_colormap)(WNativeWindow win, unsigned long *colormap_out);
|
||||
WNativeWindow (*pointer_query_window)(WNativeWindow root);
|
||||
|
|
|
|||
|
|
@ -8863,6 +8863,27 @@ static void wl_noop_event_flush_type(int t) { (void)t; }
|
|||
static int wl_noop_event_check_window(WNativeWindow win, int t) { (void)win; (void)t; return 0; }
|
||||
static int wl_noop_event_check_type(int t, WMEvent *e) { (void)t; (void)e; return 0; }
|
||||
static void wl_noop_client_send_event(WNativeWindow win, void *d) { (void)win; (void)d; }
|
||||
static void wl_client_send_key(WNativeWindow win, unsigned int keycode,
|
||||
unsigned int modifier_mask, int press)
|
||||
{
|
||||
/* For XWayland clients, deliver via the X server (wl_state.x_display)
|
||||
* the same way the X11 backend does. Native Wayland clients are not
|
||||
* yet supported (would require zwp_virtual_keyboard_v1). */
|
||||
if (!wl_state.x_display) return;
|
||||
XEvent ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.xkey.type = press ? KeyPress : KeyRelease;
|
||||
ev.xkey.display = wl_state.x_display;
|
||||
ev.xkey.window = (Window)win;
|
||||
ev.xkey.root = DefaultRootWindow(wl_state.x_display);
|
||||
ev.xkey.subwindow = None;
|
||||
ev.xkey.same_screen = True;
|
||||
ev.xkey.time = CurrentTime;
|
||||
ev.xkey.keycode = keycode;
|
||||
ev.xkey.state = modifier_mask;
|
||||
XSendEvent(wl_state.x_display, (Window)win, press ? False : True,
|
||||
press ? KeyPressMask : KeyReleaseMask, &ev);
|
||||
}
|
||||
static int wl_noop_window_exists(WNativeWindow win) { (void)win; return 1; }
|
||||
static void wl_noop_window_get_colormap(WNativeWindow win, unsigned long *c) { (void)win; (void)c; }
|
||||
static WNativeWindow wl_noop_pointer_query_window(WNativeWindow root) { (void)root; return WNATIVE_NONE; }
|
||||
|
|
@ -9144,6 +9165,7 @@ const WMBackend wl_backend = {
|
|||
.event_check_window = wl_noop_event_check_window,
|
||||
.event_check_type = wl_noop_event_check_type,
|
||||
.client_send_event = wl_noop_client_send_event,
|
||||
.client_send_key = wl_client_send_key,
|
||||
.window_exists = wl_noop_window_exists,
|
||||
.window_get_colormap = wl_noop_window_get_colormap,
|
||||
.pointer_query_window = wl_noop_pointer_query_window,
|
||||
|
|
|
|||
|
|
@ -3540,6 +3540,24 @@ static void x11_client_send_event(WNativeWindow win, void *event_data)
|
|||
{
|
||||
XSendEvent(dpy, (Window)win, False, 0L, (XEvent *)event_data);
|
||||
}
|
||||
|
||||
static void x11_client_send_key(WNativeWindow win, unsigned int keycode,
|
||||
unsigned int modifier_mask, int press)
|
||||
{
|
||||
XEvent ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.xkey.type = press ? KeyPress : KeyRelease;
|
||||
ev.xkey.display = dpy;
|
||||
ev.xkey.window = (Window)win;
|
||||
ev.xkey.root = DefaultRootWindow(dpy);
|
||||
ev.xkey.subwindow = None;
|
||||
ev.xkey.same_screen = True;
|
||||
ev.xkey.time = CurrentTime;
|
||||
ev.xkey.keycode = keycode;
|
||||
ev.xkey.state = modifier_mask;
|
||||
XSendEvent(dpy, (Window)win, press ? False : True,
|
||||
press ? KeyPressMask : KeyReleaseMask, &ev);
|
||||
}
|
||||
static int x11_window_exists(WNativeWindow win)
|
||||
{
|
||||
Window jr; int ji; unsigned int ju;
|
||||
|
|
@ -4645,6 +4663,7 @@ const WMBackend x11_backend = {
|
|||
.event_check_window = x11_event_check_window,
|
||||
.event_check_type = x11_event_check_type,
|
||||
.client_send_event = x11_client_send_event,
|
||||
.client_send_key = x11_client_send_key,
|
||||
.window_exists = x11_window_exists,
|
||||
.window_get_colormap = x11_window_get_colormap,
|
||||
.pointer_query_window = x11_pointer_query_window,
|
||||
|
|
|
|||
25
src/misc.c
25
src/misc.c
|
|
@ -617,31 +617,6 @@ void ParseWindowName(WMPropList *value, char **winstance, char **wclass, const c
|
|||
UnescapeWM_CLASS(name, winstance, wclass);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static char *keysymToString(KeySym keysym, unsigned int state)
|
||||
{
|
||||
XKeyEvent kev;
|
||||
char *buf = wmalloc(20);
|
||||
int count;
|
||||
|
||||
kev.display = dpy;
|
||||
kev.type = KeyPress;
|
||||
kev.send_event = False;
|
||||
kev.window = DefaultRootWindow(dpy);
|
||||
kev.root = DefaultRootWindow(dpy);
|
||||
kev.same_screen = True;
|
||||
kev.subwindow = kev.root;
|
||||
kev.serial = 0x12344321;
|
||||
kev.time = CurrentTime;
|
||||
kev.state = state;
|
||||
kev.keycode = XKeysymToKeycode(dpy, keysym);
|
||||
count = XLookupString(&kev, buf, 19, NULL, NULL);
|
||||
buf[count] = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *GetShortcutString(const char *shortcut)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
|
|
|
|||
|
|
@ -86,10 +86,9 @@ typedef struct {
|
|||
|
||||
static void notifyClient(WMenu *menu, WMenuEntry *entry)
|
||||
{
|
||||
XEvent event;
|
||||
WUserMenuData *data = entry->clientdata;
|
||||
WScreen *scr = data->screen;
|
||||
Window window;
|
||||
WNativeWindow window;
|
||||
int i;
|
||||
|
||||
(void) menu;
|
||||
|
|
@ -97,26 +96,10 @@ static void notifyClient(WMenu *menu, WMenuEntry *entry)
|
|||
window = scr->focused_window->client_win;
|
||||
|
||||
for (i = 0; i < data->key_no; i++) {
|
||||
event.xkey.type = KeyPress;
|
||||
event.xkey.display = dpy;
|
||||
event.xkey.window = window;
|
||||
event.xkey.root = DefaultRootWindow(dpy);
|
||||
event.xkey.subwindow = (Window) None;
|
||||
event.xkey.x = 0x0;
|
||||
event.xkey.y = 0x0;
|
||||
event.xkey.x_root = 0x0;
|
||||
event.xkey.y_root = 0x0;
|
||||
event.xkey.keycode = data->key[i].keycode;
|
||||
event.xkey.state = data->key[i].modifier;
|
||||
event.xkey.same_screen = True;
|
||||
event.xkey.time = CurrentTime;
|
||||
if (dpy) {
|
||||
if (XSendEvent(dpy, window, False, KeyPressMask, &event)) {
|
||||
event.xkey.type = KeyRelease;
|
||||
event.xkey.time = CurrentTime;
|
||||
XSendEvent(dpy, window, True, KeyReleaseMask, &event);
|
||||
}
|
||||
}
|
||||
wm_backend->client_send_key(window, data->key[i].keycode,
|
||||
data->key[i].modifier, 1 /*press*/);
|
||||
wm_backend->client_send_key(window, data->key[i].keycode,
|
||||
data->key[i].modifier, 0 /*release*/);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue