]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
get rid of the plate window
[chaz/openbox] / openbox / event.c
index 6e11f82eac819dcf8fff9addb8c10e8f27c723fd..2ea7d30442a688f7bde0a2897169f5f2fbef6749 100644 (file)
@@ -270,6 +270,8 @@ static void event_hack_mods(XEvent *e)
             XEvent ce;
             while (XCheckTypedWindowEvent(ob_display, e->xmotion.window,
                                           e->type, &ce)) {
+                e->xmotion.x = ce.xmotion.x;
+                e->xmotion.y = ce.xmotion.y;
                 e->xmotion.x_root = ce.xmotion.x_root;
                 e->xmotion.y_root = ce.xmotion.y_root;
             }
@@ -304,7 +306,9 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
             /* This means focus reverted off of a client */
             else if (detail == NotifyPointerRoot ||
                      detail == NotifyDetailNone ||
-                     detail == NotifyInferior)
+                     detail == NotifyInferior ||
+                     /* This means focus got here from another screen */
+                     detail == NotifyNonlinear)
                 return TRUE;
             else
                 return FALSE;
@@ -343,6 +347,9 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
         /* This means focus was taken by a keyboard/mouse grab. */
         if (mode == NotifyGrab)
             return FALSE;
+        /* This means focus was grabbed on a window and it was released. */
+        if (mode == NotifyUngrab)
+            return FALSE;
 
         /* Focus left the root window revertedto state */
         if (win == RootWindow(ob_display, ob_screen))
@@ -482,12 +489,20 @@ static void event_process(const XEvent *ec, gpointer data)
     } else if (e->type == FocusIn) {
         if (e->xfocus.detail == NotifyPointerRoot ||
             e->xfocus.detail == NotifyDetailNone ||
-            e->xfocus.detail == NotifyInferior)
+            e->xfocus.detail == NotifyInferior ||
+            e->xfocus.detail == NotifyNonlinear)
         {
             XEvent ce;
 
-            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none or"
-                          " the frame window\n");
+            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to root, "
+                          "pointer root/none or "
+                          "the frame window\n");
+
+            if (e->xfocus.detail == NotifyInferior ||
+                e->xfocus.detail == NotifyNonlinear)
+            {
+                focus_left_screen = FALSE;
+            }
 
             /* If another FocusIn is in the queue then don't fallback yet. This
                fixes the fun case of:
@@ -516,7 +531,7 @@ static void event_process(const XEvent *ec, gpointer data)
                 */
 
                 if (!focus_left_screen)
-                    focus_fallback(TRUE);
+                    focus_fallback(TRUE, FALSE);
             }
         }
         else if (!client)
@@ -536,16 +551,8 @@ static void event_process(const XEvent *ec, gpointer data)
             client_bring_helper_windows(client);
         }
     } else if (e->type == FocusOut) {
-        gboolean nomove = FALSE;
         XEvent ce;
 
-        if (client) {
-            frame_adjust_focus(client->frame, FALSE);
-            /* focus_set_client(NULL) has already been called in this
-               section or by focus_fallback */
-            client_calc_layer(client);
-        }
-
         /* Look for the followup FocusIn */
         if (!XCheckIfEvent(ob_display, &ce, event_look_for_focusin, NULL)) {
             /* There is no FocusIn, this means focus went to a window that
@@ -578,9 +585,16 @@ 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 && client != focus_client) {
+            frame_adjust_focus(client->frame, FALSE);
+            /* focus_set_client(NULL) has already been called in this
+               section or by focus_fallback */
+            client_calc_layer(client);
+        }
     } else if (timewinclients)
         event_handle_user_time_window_clients(timewinclients, e);
     else if (client)
@@ -995,26 +1009,26 @@ 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);
+        ob_debug("ConfigureRequest for \"%s\" desktop %d wmstate %d "
+                 "visibile %d\n"
+                 "                     x %d y %d w %d h %d b %d\n",
+                 client->title,
+                 screen_desktop, client->wmstate, client->frame->visible,
+                 x, y, w, h, b);
 
         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;
             }
 
 
@@ -1038,10 +1052,10 @@ static void event_handle_client(ObClient *client, XEvent *e)
             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) ||
+            (e->xconfigurerequest.value_mask & CWY) ||
+            (e->xconfigurerequest.value_mask & CWWidth) ||
+            (e->xconfigurerequest.value_mask & CWHeight))
         {
             if (e->xconfigurerequest.value_mask & CWX) {
                 /* don't allow clients to move shaded windows (fvwm does this)
@@ -1061,20 +1075,10 @@ static void event_handle_client(ObClient *client, XEvent *e)
             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);
             }
         }
 
@@ -1114,17 +1118,35 @@ 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_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
+
+                /* 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 & CWWidth &&
+                     !(e->xconfigurerequest.value_mask & CWX)))
+                    client_gravity_resize_w(client, &x, client->area.width, w);
+                /* 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 & CWHeight &&
+                     !(e->xconfigurerequest.value_mask & CWY)))
+                    client_gravity_resize_h(client, &y, client->area.height,h);
+
+                client_find_onscreen(client, &x, &y, w, h, 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)) {
-                ob_debug("Doing configure\n");
-                client_configure(client, x, y, w, h, FALSE, TRUE);
+            if (move || !RECT_EQUAL_DIMS(client->area, x, y, w, h) ||
+                border)
+            {
+                ob_debug("Granting ConfigureRequest x %d y %d w %d h %d "
+                         "b %d\n",
+                         x, y, w, h, b);
+                client_configure(client, x, y, w, h, b, FALSE, TRUE);
             }
 
             /* ignore enter events caused by these like ob actions do */
@@ -1149,7 +1171,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
         break;
     case ReparentNotify:
         /* this is when the client is first taken captive in the frame */
-        if (e->xreparent.parent == client->frame->plate) break;
+        if (e->xreparent.parent == client->frame->window) break;
 
         /*
           This event is quite rare and is usually handled in unmapHandler.
@@ -1329,7 +1351,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;
 
@@ -1417,7 +1440,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
         if (msgtype == XA_WM_NORMAL_HINTS) {
             client_update_normal_hints(client);
             /* normal hints can make a window non-resizable */
-            client_setup_decor_and_functions(client);
+            client_setup_decor_and_functions(client, TRUE);
         } else if (msgtype == XA_WM_HINTS) {
             client_update_wmhints(client);
         } else if (msgtype == XA_WM_TRANSIENT_FOR) {
@@ -1425,7 +1448,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_get_type_and_transientness(client);
             /* type may have changed, so update the layer */
             client_calc_layer(client);
-            client_setup_decor_and_functions(client);
+            client_setup_decor_and_functions(client, TRUE);
         } else if (msgtype == prop_atoms.net_wm_name ||
                    msgtype == prop_atoms.wm_name ||
                    msgtype == prop_atoms.net_wm_icon_name ||
@@ -1433,11 +1456,14 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_update_title(client);
         } else if (msgtype == prop_atoms.wm_protocols) {
             client_update_protocols(client);
-            client_setup_decor_and_functions(client);
+            client_setup_decor_and_functions(client, TRUE);
         }
         else if (msgtype == prop_atoms.net_wm_strut) {
             client_update_strut(client);
         }
+        else if (msgtype == prop_atoms.net_wm_strut_partial) {
+            client_update_strut(client);
+        }
         else if (msgtype == prop_atoms.net_wm_icon) {
             client_update_icons(client);
         }
@@ -1455,6 +1481,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;
@@ -1566,7 +1593,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);
     }
 
@@ -1588,8 +1615,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. */
@@ -1665,8 +1692,11 @@ static gboolean event_handle_menu(XEvent *ev)
         {
             if ((e = menu_entry_frame_under(ev->xbutton.x_root,
                                             ev->xbutton.y_root)))
+            {
+                menu_frame_select(e->frame, e, TRUE);
                 menu_entry_frame_execute(e, ev->xbutton.state,
                                          ev->xbutton.time);
+            }
             else
                 menu_frame_hide_all();
         }
@@ -1675,7 +1705,10 @@ static gboolean event_handle_menu(XEvent *ev)
         if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window))) {
             if (e->ignore_enters)
                 --e->ignore_enters;
-            else
+            else if (!(f = find_active_menu()) ||
+                     f == e->frame ||
+                     f->parent == e->frame ||
+                     f->child == e->frame)
                 menu_frame_select(e->frame, e, FALSE);
         }
         break;
@@ -1694,7 +1727,11 @@ static gboolean event_handle_menu(XEvent *ev)
     case MotionNotify:   
         if ((e = menu_entry_frame_under(ev->xmotion.x_root,   
                                         ev->xmotion.y_root)))
-            menu_frame_select(e->frame, e, FALSE);
+            if (!(f = find_active_menu()) ||
+                f == e->frame ||
+                f->parent == e->frame ||
+                f->child == e->frame)
+                menu_frame_select(e->frame, e, FALSE);
         break;
     case KeyPress:
         ret = event_handle_menu_keyboard(ev);
@@ -1837,6 +1874,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.03273 seconds and 4 git commands to generate.