]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
change in how things are ungrabbed to avoid grabwhilenotify. don't ungrab every key...
[chaz/openbox] / openbox / event.c
index d7c723d120f1abbc1708f2ddbddf7b84305975b0..e7ef27fb3058b1ab7ca6942c3a582463cde39d32 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,7 +509,7 @@ 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
@@ -554,12 +561,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) {
@@ -572,10 +575,10 @@ static void event_process(const XEvent *ec, gpointer data)
             }
         }
 
-        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)
@@ -679,7 +682,7 @@ static void event_handle_root(XEvent *e)
             }
         } else if (msgtype == prop_atoms.net_number_of_desktops) {
             guint d = e->xclient.data.l[0];
-            if (d > 0)
+            if (d > 0 && d <= 1000)
                 screen_set_num_desktops(d);
         } else if (msgtype == prop_atoms.net_showing_desktop) {
             screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
@@ -1035,38 +1038,43 @@ static void event_handle_client(ObClient *client, XEvent *e)
             move = TRUE;
         }
 
-        /* don't allow clients to move shaded windows (fvwm does this) */
-        if (client->shaded && (e->xconfigurerequest.value_mask & CWX ||
-                               e->xconfigurerequest.value_mask & CWY))
-        {
-            e->xconfigurerequest.value_mask &= ~CWX;
-            e->xconfigurerequest.value_mask &= ~CWY;
-
-            /* if the client tried to move and we aren't letting it then a
-               synthetic event is needed */
-            move = TRUE;
-        }
-
         if (e->xconfigurerequest.value_mask & CWX ||
             e->xconfigurerequest.value_mask & CWY ||
             e->xconfigurerequest.value_mask & CWWidth ||
             e->xconfigurerequest.value_mask & CWHeight)
         {
             if (e->xconfigurerequest.value_mask & CWX) {
-                x = e->xconfigurerequest.x;
+                /* don't allow clients to move shaded windows (fvwm does this)
+                 */
+                if (!client->shaded)
+                    x = e->xconfigurerequest.x;
                 move = TRUE;
             }
             if (e->xconfigurerequest.value_mask & CWY) {
-                y = e->xconfigurerequest.y;
+                /* don't allow clients to move shaded windows (fvwm does this)
+                 */
+                if (!client->shaded)
+                    y = e->xconfigurerequest.y;
                 move = TRUE;
             }
+
             if (e->xconfigurerequest.value_mask & CWWidth) {
                 w = e->xconfigurerequest.width;
                 resize = TRUE;
+
+                /* if x was not given, then use gravity to figure out the new
+                   x.  the reference point should not be moved */
+                if (!(e->xconfigurerequest.value_mask & CWX))
+                    client_gravity_resize_w(client, &x, client->area.width, w);
             }
             if (e->xconfigurerequest.value_mask & CWHeight) {
                 h = e->xconfigurerequest.height;
                 resize = TRUE;
+
+                /* if y was not given, then use gravity to figure out the new
+                   y.  the reference point should not be moved */
+                if (!(e->xconfigurerequest.value_mask & CWY))
+                    client_gravity_resize_h(client, &y, client->area.height,h);
             }
         }
 
@@ -1276,12 +1284,12 @@ static void event_handle_client(ObClient *client, XEvent *e)
                      prop_atoms.net_wm_moveresize_cancel)
                 moveresize_end(TRUE);
         } else if (msgtype == prop_atoms.net_moveresize_window) {
-            gint grav, x, y, w, h;
+            gint ograv, x, y, w, h;
+
+            ograv = client->gravity;
 
             if (e->xclient.data.l[0] & 0xff)
-                grav = e->xclient.data.l[0] & 0xff;
-            else 
-                grav = client->gravity;
+                client->gravity = e->xclient.data.l[0] & 0xff;
 
             if (e->xclient.data.l[0] & 1 << 8)
                 x = e->xclient.data.l[1];
@@ -1291,23 +1299,40 @@ static void event_handle_client(ObClient *client, XEvent *e)
                 y = e->xclient.data.l[2];
             else
                 y = client->area.y;
-            if (e->xclient.data.l[0] & 1 << 10)
+
+            if (e->xclient.data.l[0] & 1 << 10) {
                 w = e->xclient.data.l[3];
+
+                /* if x was not given, then use gravity to figure out the new
+                   x.  the reference point should not be moved */
+                if (!(e->xclient.data.l[0] & 1 << 8))
+                    client_gravity_resize_w(client, &x, client->area.width, w);
+            }
             else
                 w = client->area.width;
-            if (e->xclient.data.l[0] & 1 << 11)
+
+            if (e->xclient.data.l[0] & 1 << 11) {
                 h = e->xclient.data.l[4];
+
+                /* if y was not given, then use gravity to figure out the new
+                   y.  the reference point should not be moved */
+                if (!(e->xclient.data.l[0] & 1 << 9))
+                    client_gravity_resize_h(client, &y, client->area.height,h);
+            }
             else
                 h = client->area.height;
 
-            ob_debug("MOVERESIZE x %d %d y %d %d\n",
+            ob_debug("MOVERESIZE x %d %d y %d %d (gravity %d)\n",
                      e->xclient.data.l[0] & 1 << 8, x,
-                     e->xclient.data.l[0] & 1 << 9, y);
-            client_convert_gravity(client, grav, &x, &y, w, h);
+                     e->xclient.data.l[0] & 1 << 9, y,
+                     client->gravity);
+
             client_find_onscreen(client, &x, &y, w, h, FALSE);
 
             client_configure(client, x, y, w, h, FALSE, TRUE);
 
+            client->gravity = ograv;
+
             /* ignore enter events caused by these like ob actions do */
             event_ignore_all_queued_enters();
         } else if (msgtype == prop_atoms.net_restack_window) {
@@ -1563,8 +1588,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. */
@@ -1812,6 +1837,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.025779 seconds and 4 git commands to generate.