change in how things are ungrabbed to avoid grabwhilenotify. don't ungrab every key press. just ungrab the passive grab when there is no active grab and we are going to move focus. this should be less intrusive and seems to work
Dana Jansens danakj@orodu.net
6 files changed,
84 insertions(+),
19 deletions(-)
M
openbox/action.c
→
openbox/action.c
@@ -1216,11 +1216,9 @@ gchar *cmd, **argv = 0;
if (data->execute.path) { cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL); if (cmd) { - /* If there is an interactive action going on, then cancel it - to release the keyboard, so that the run application - can grab the keyboard if it wants to. */ - if (keyboard_interactively_grabbed()) - keyboard_interactive_cancel(); + /* If there is a keyboard grab going on then we need to cancel + it so the application can grab things */ + event_cancel_all_key_grabs(); if (!g_shell_parse_argv (cmd, NULL, &argv, &e)) { g_message(_("Failed to execute '%s': %s"),
M
openbox/client.c
→
openbox/client.c
@@ -2540,8 +2540,7 @@
actions should not rely on being able to move focus during an interactive grab. */ - if (keyboard_interactively_grabbed()) - keyboard_interactive_cancel(); + event_cancel_all_key_grabs(); } frame_hide(self->frame);@@ -3526,8 +3525,7 @@
actions should not rely on being able to move focus during an interactive grab. */ - if (keyboard_interactively_grabbed()) - keyboard_interactive_cancel(); + event_cancel_all_key_grabs(); xerror_set_ignore(TRUE); xerror_occured = FALSE;
M
openbox/event.c
→
openbox/event.c
@@ -1837,6 +1837,25 @@ }
return FALSE; } +void event_cancel_all_key_grabs() +{ + if (keyboard_interactively_grabbed()) + keyboard_interactive_cancel(); + else if (menu_frame_visible) + menu_frame_hide_all(); + else if (grab_on_keyboard()) + ungrab_keyboard(); + else + /* If we don't have the keyboard grabbed, then ungrab it with + XUngrabKeyboard, so that there is not a passive grab left + on from the KeyPress. If the grab is left on, and focus + moves during that time, it will be NotifyWhileGrabbed, and + applications like to ignore those! */ + if (!keyboard_interactively_grabbed()) + XUngrabKeyboard(ob_display, CurrentTime); + +} + gboolean event_time_after(Time t1, Time t2) { g_assert(t1 != CurrentTime);
M
openbox/event.h
→
openbox/event.h
@@ -43,6 +43,9 @@ /*! Make mouse focus not move at all from the stuff that has happened up
till now. */ void event_ignore_all_queued_enters(); +/*! End *all* active and passive grabs on the keyboard */ +void event_cancel_all_key_grabs(); + /* Halts any focus delay in progress, use this when the user is selecting a window for focus */ void event_halt_focus_delay();
M
openbox/keyboard.c
→
openbox/keyboard.c
@@ -311,14 +311,6 @@ set_curpos(p);
else { keyboard_reset_chains(0); - /* If we don't have the keyboard grabbed, then ungrab it with - XUngrabKeyboard, so that there is not a passive grab left - on from the KeyPress. If the grab is left on, and focus - moves during that time, it will be NotifyWhileGrabbed, and - applications like to ignore those! */ - if (!keyboard_interactively_grabbed()) - XUngrabKeyboard(ob_display, e->xkey.time); - action_run_key(p->actions, client, e->xkey.state, e->xkey.x_root, e->xkey.y_root, e->xkey.time);
M
tests/focusout.c
→
tests/focusout.c
@@ -47,7 +47,8 @@
XSetWindowBackground(display,win,WhitePixel(display,0)); XSetWindowBackground(display,child,BlackPixel(display,0)); - XSelectInput(display, win, FocusChangeMask); + XSelectInput(display, win, + FocusChangeMask|EnterWindowMask|LeaveWindowMask); XMapWindow(display, win); XMapWindow(display, child);@@ -157,8 +158,62 @@ printf("window : 0x%x\n", report.xfocus.window);
printf("mode : %s\n", mode); printf("detail : %s\n", detail); printf("---\n"); - } + break; + case EnterNotify: + switch (report.xcrossing.mode) { + case NotifyNormal: mode = "NotifyNormal"; break; + case NotifyGrab: mode = "NotifyGrab"; break; + case NotifyUngrab: mode = "NotifyUngrab"; break; + } + switch (report.xcrossing.detail) { + case NotifyAncestor: detail = "NotifyAncestor"; break; + case NotifyVirtual: detail = "NotifyVirtual"; break; + case NotifyInferior: detail = "NotifyInferior"; break; + case NotifyNonlinear: detail = "NotifyNonlinear"; break; + case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; + case NotifyPointer: detail = "NotifyPointer"; break; + case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; + case NotifyDetailNone: detail = "NotifyDetailNone"; break; + } + printf("enternotify\n"); + printf("type : %d\n", report.xcrossing.type); + printf("serial : %d\n", report.xcrossing.serial); + printf("send_event: %d\n", report.xcrossing.send_event); + printf("display : 0x%x\n", report.xcrossing.display); + printf("window : 0x%x\n", report.xcrossing.window); + printf("mode : %s\n", mode); + printf("detail : %s\n", detail); + printf("---\n"); + break; + case LeaveNotify: + switch (report.xcrossing.mode) { + case NotifyNormal: mode = "NotifyNormal"; break; + case NotifyGrab: mode = "NotifyGrab"; break; + case NotifyUngrab: mode = "NotifyUngrab"; break; + } + + switch (report.xcrossing.detail) { + case NotifyAncestor: detail = "NotifyAncestor"; break; + case NotifyVirtual: detail = "NotifyVirtual"; break; + case NotifyInferior: detail = "NotifyInferior"; break; + case NotifyNonlinear: detail = "NotifyNonlinear"; break; + case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; + case NotifyPointer: detail = "NotifyPointer"; break; + case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; + case NotifyDetailNone: detail = "NotifyDetailNone"; break; + } + printf("leavenotify\n"); + printf("type : %d\n", report.xcrossing.type); + printf("serial : %d\n", report.xcrossing.serial); + printf("send_event: %d\n", report.xcrossing.send_event); + printf("display : 0x%x\n", report.xcrossing.display); + printf("window : 0x%x\n", report.xcrossing.window); + printf("mode : %s\n", mode); + printf("detail : %s\n", detail); + printf("---\n"); + break; + } } return 1;