]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
make focuslast only apply to switching desktops, like 3.3.1
[chaz/openbox] / openbox / event.c
index c19f70175d1567323b8a28a906cd70e476f3b094..9eaec027758df48d3ec127fa2bd533a07fa9fd81 100644 (file)
@@ -319,6 +319,12 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
             if (!w || !WINDOW_IS_CLIENT(w))
                 return FALSE;
         }
+        else {
+            /* This means focus reverted to parent from the client (this
+               happens often during iconify animation) */
+            if (detail == NotifyInferior)
+                return TRUE;
+        }
 
         /* This means focus moved from the root window to a client */
         if (detail == NotifyVirtual)
@@ -480,7 +486,8 @@ static void event_process(const XEvent *ec, gpointer data)
         {
             XEvent ce;
 
-            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none\n");
+            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none or"
+                          " the frame window\n");
 
             /* If another FocusIn is in the queue then don't fallback yet. This
                fixes the fun case of:
@@ -502,14 +509,14 @@ static void event_process(const XEvent *ec, gpointer data)
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "  but another FocusIn is coming\n");
             } else {
-                /* Focus has been reverted to the root window or nothing.
+                /* Focus has been reverted.
 
                    FocusOut events come after UnmapNotify, so we don't need to
                    worry about focusing an invalid window
                 */
 
                 if (!focus_left_screen)
-                    focus_fallback(TRUE);
+                    focus_fallback(TRUE, FALSE);
             }
         }
         else if (!client)
@@ -529,7 +536,6 @@ static void event_process(const XEvent *ec, gpointer data)
             client_bring_helper_windows(client);
         }
     } else if (e->type == FocusOut) {
-        gboolean nomove = FALSE;
         XEvent ce;
 
         /* Look for the followup FocusIn */
@@ -554,12 +560,8 @@ static void event_process(const XEvent *ec, gpointer data)
             xerror_set_ignore(FALSE);
             /* nothing is focused */
             focus_set_client(NULL);
-        } else if (ce.xany.window == e->xany.window) {
-            ob_debug_type(OB_DEBUG_FOCUS, "Focus didn't go anywhere\n");
-            /* If focus didn't actually move anywhere, there is nothing to do*/
-            nomove = TRUE;
         } else {
-            /* Focus did move, so process the FocusIn event */
+            /* Focus moved, so process the FocusIn event */
             ObEventData ed = { .ignored = FALSE };
             event_process(&ce, &ed);
             if (ed.ignored) {
@@ -568,14 +570,14 @@ static void event_process(const XEvent *ec, gpointer data)
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Focus went to an unmanaged window 0x%x !\n",
                               ce.xfocus.window);
-                focus_fallback(TRUE);
+                focus_fallback(TRUE, FALSE);
             }
         }
 
-        if (client && !nomove) {
+        if (client && client != focus_client) {
             frame_adjust_focus(client->frame, FALSE);
-            if (client == focus_client)
-                focus_set_client(NULL);
+            /* focus_set_client(NULL) has already been called in this
+               section or by focus_fallback */
             client_calc_layer(client);
         }
     } else if (timewinclients)
@@ -992,26 +994,22 @@ static void event_handle_client(ObClient *client, XEvent *e)
            also you can't compress stacking events
         */
 
-        gint x, y, w, h;
+        gint x, y, w, h, b;
         gboolean move = FALSE;
         gboolean resize = FALSE;
+        gboolean border = FALSE;
 
         /* get the current area */
         RECT_TO_DIMS(client->area, x, y, w, h);
+        b = client->border_width;
 
         ob_debug("ConfigureRequest desktop %d wmstate %d visibile %d\n",
                  screen_desktop, client->wmstate, client->frame->visible);
 
         if (e->xconfigurerequest.value_mask & CWBorderWidth)
             if (client->border_width != e->xconfigurerequest.border_width) {
-                client->border_width = e->xconfigurerequest.border_width;
-
-                /* if the border width is changing then that is the same
-                   as requesting a resize, but we don't actually change
-                   the client's border, so it will change their root
-                   coordiantes (since they include the border width) and
-                   we need to a notify then */
-                move = TRUE;
+                b = e->xconfigurerequest.border_width;
+                border = TRUE;
             }
 
 
@@ -1111,17 +1109,21 @@ static void event_handle_client(ObClient *client, XEvent *e)
                notify is sent or not */
         }
 
-        if (move || resize) {
+        if (move || resize || border) {
             gint lw,lh;
 
-            client_find_onscreen(client, &x, &y, w, h, FALSE);
-            client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
+            if (move || resize) {
+                client_find_onscreen(client, &x, &y, w, h, FALSE);
+                client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
+            }
             /* if they requested something that moves the window, or if
                the window is actually being changed then configure it and
                send a configure notify to them */
-            if (move || !RECT_EQUAL_DIMS(client->area, x, y, w, h)) {
+            if (move || !RECT_EQUAL_DIMS(client->area, x, y, w, h) ||
+                border)
+            {
                 ob_debug("Doing configure\n");
-                client_configure(client, x, y, w, h, FALSE, TRUE);
+                client_configure(client, x, y, w, h, b, FALSE, TRUE);
             }
 
             /* ignore enter events caused by these like ob actions do */
@@ -1326,7 +1328,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
 
             client_find_onscreen(client, &x, &y, w, h, FALSE);
 
-            client_configure(client, x, y, w, h, FALSE, TRUE);
+            client_configure(client, x, y, w, h, client->border_width,
+                             FALSE, TRUE);
 
             client->gravity = ograv;
 
@@ -1452,6 +1455,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_update_sync_request_counter(client);
         }
 #endif
+        break;
     case ColormapNotify:
         client_update_colormap(client, e->xcolormap.colormap);
         break;
@@ -1563,7 +1567,7 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
            Control-Enter runs it without closing the menu. */
         if (frame->child)
             menu_frame_select_next(frame->child);
-        else
+        else if (frame->selected)
             menu_entry_frame_execute(frame->selected, state, ev->xkey.time);
     }
 
@@ -1585,8 +1589,8 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
         menu_frame_select_next(frame);
     }
 
-    /* keyboard accelerator shortcuts. */
-    else if (ev->xkey.state == 0 &&
+    /* keyboard accelerator shortcuts. (allow controlmask) */
+    else if ((ev->xkey.state & ~ControlMask) == 0 &&
              /* was it a valid key? */
              unikey != 0 &&
              /* don't bother if the menu is empty. */
@@ -1834,6 +1838,25 @@ static gboolean is_enter_focus_event_ignored(XEvent *e)
     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);
This page took 0.028738 seconds and 4 git commands to generate.