inline void client_action_end(union ActionData *data)
{
if (config_focus_follow)
- if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button)
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
+ if (data->any.context != OB_FRAME_CONTEXT_CLIENT) {
+ if (!data->any.button) {
+ grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
+ } else {
+ ObClient *c;
+
+ /* usually this is sorta redundant, but with a press action
+ that moves windows our from under the cursor, the enter
+ event will come as a GrabNotify which is ignored, so this
+ makes a fake enter event
+ */
+ if ((c = client_under_pointer()))
+ event_enter_client(c);
+ }
+ }
}
typedef struct
}
}
- if (!inter) {
- /* sometimes when we execute another app as an action,
- it won't work right unless we XUngrabKeyboard first,
- even though we grabbed the key/button Asychronously.
- e.g. "gnome-panel-control --main-menu" */
- grab_keyboard(FALSE);
+ if (!inter && button == 0) {
+ /* Ungrab the keyboard before running the action, if it was
+ not from a mouse event.
+
+ We have to do this because a key press causes a passive
+ grab on the keyboard, and so if the action we are running
+ wants to grab the keyboard, it will fail if the button is still
+ held down (which is likely).
+
+ Use the X function not out own, because we're not considering
+ a grab to be in place at all so our function won't try ungrab
+ anything.
+ */
+ XUngrabKeyboard(ob_display, time);
}
for (it = acts; it; it = g_slist_next(it)) {
{
/* interactive actions are not queued */
a->func(&a->data);
- } else if ((context == OB_FRAME_CONTEXT_CLIENT ||
- (c && c->type == OB_CLIENT_TYPE_DESKTOP &&
+ } else if (c &&
+ (context == OB_FRAME_CONTEXT_CLIENT ||
+ (c->type == OB_CLIENT_TYPE_DESKTOP &&
context == OB_FRAME_CONTEXT_DESKTOP)) &&
(a->func == action_focus ||
a->func == action_activate ||
{
if (data->client.any.c) {
if (!data->any.button || client_mouse_focusable(data->client.any.c) ||
- data->any.context != OB_FRAME_CONTEXT_CLIENT)
+ (data->any.context != OB_FRAME_CONTEXT_CLIENT &&
+ data->any.context != OB_FRAME_CONTEXT_FRAME))
{
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
{
if (data->client.any.c) {
if (!data->any.button || client_mouse_focusable(data->client.any.c) ||
- data->any.context != OB_FRAME_CONTEXT_CLIENT)
+ (data->any.context != OB_FRAME_CONTEXT_CLIENT &&
+ data->any.context != OB_FRAME_CONTEXT_FRAME))
{
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
void action_unfocus (union ActionData *data)
{
if (data->client.any.c == focus_client)
- focus_fallback(FALSE);
+ focus_fallback(TRUE);
}
void action_iconify(union ActionData *data)