From 5bca4a0a26f89c70357fbbbe13ad1fe9d3b07b24 Mon Sep 17 00:00:00 2001 From: John Ankarstrom Date: Wed, 30 Jun 2021 19:30:09 +0200 Subject: Use enter and escape keys to navigate confirmation dialog --- src/confirm.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/confirm.c b/src/confirm.c index 77aa48e..e71735a 100644 --- a/src/confirm.c +++ b/src/confirm.c @@ -15,6 +15,7 @@ #include "button.h" #include "screen.h" #include "color.h" +#include "key.h" #include "misc.h" #ifndef DISABLE_CONFIRM @@ -58,6 +59,7 @@ static void DrawButtons(DialogType *d); static DialogType *FindDialogByWindow(Window w); static int HandleDialogExpose(const XExposeEvent *event); static int HandleDialogButtonRelease(const XButtonEvent *event); +static int HandleDialogKey(const XKeyEvent *event); /** Initialize the dialog processing data. */ void InitializeDialogs() { @@ -92,6 +94,9 @@ int ProcessDialogEvent(const XEvent *event) { return HandleDialogExpose(&event->xexpose); case ButtonRelease: return HandleDialogButtonRelease(&event->xbutton); + case KeyPress: + case KeyRelease: + return HandleDialogKey(&event->xkey); default: break; } @@ -154,6 +159,35 @@ int HandleDialogButtonRelease(const XButtonEvent *event) { } +/** Handle a key release event. */ +int HandleDialogKey(const XKeyEvent *event) { + static int enter = 0; + + ClientNode *np; + DialogType *dp; + + Assert(event); + + if(!(np = GetActiveClient())) + return 0; + if(!(dp = FindDialogByWindow(np->window))) + return 0; + + switch(GetKey(event) & 0xFF) { + case KEY_ENTER: + /* Ignore release without preceding press. */ + if(event->type == KeyPress && ++enter || !enter || --enter) + break; + (dp->action)(dp->client); + /* FALLTHROUGH */ + case KEY_ESC: + DestroyConfirmDialog(dp); + break; + } + + return 1; +} + /** Find a dialog by window or frame. */ DialogType *FindDialogByWindow(Window w) { @@ -235,6 +269,8 @@ void ShowConfirmDialog(ClientNode *np, void (*action)(ClientNode*), ...) { JXGrabButton(display, AnyButton, AnyModifier, window, True, ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); + JXGrabKeyboard(display, window, False, + GrabModeAsync, GrabModeAsync, CurrentTime); } @@ -274,6 +310,8 @@ void DestroyConfirmDialog(DialogType *dp) { } Release(dp); + JXUngrabKeyboard(display, CurrentTime); + } /** Compute the size of a dialog window. */ -- cgit v1.2.3