]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
woa.. let you do mouse actions while in an interactive keyboard action, and let you...
[chaz/openbox] / openbox / event.c
index c00212f849a221b07027bcb8955aced902872ea8..efef0faa3e1f7c97c5f45f65f436aab9474d0932 100644 (file)
@@ -31,6 +31,7 @@
 #include "menu.h"
 #include "menuframe.h"
 #include "keyboard.h"
+#include "modkeys.h"
 #include "mouse.h"
 #include "mainloop.h"
 #include "framerender.h"
@@ -93,22 +94,9 @@ static gboolean menu_hide_delay_func(gpointer data);
 /* The time for the current event being processed */
 Time event_curtime = CurrentTime;
 
-/*! The value of the mask for the NumLock modifier */
-guint NumLockMask;
-/*! The value of the mask for the ScrollLock modifier */
-guint ScrollLockMask;
-/*! The key codes for the modifier keys */
-static XModifierKeymap *modmap;
-/*! Table of the constant modifier masks */
-static const gint mask_table[] = {
-    ShiftMask, LockMask, ControlMask, Mod1Mask,
-    Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
-};
-static gint mask_table_size;
-
 static guint ignore_enter_focus = 0;
-
 static gboolean menu_can_hide;
+static gboolean focus_left_screen = FALSE;
 
 #ifdef USE_SM
 static void ice_handler(gint fd, gpointer conn)
@@ -136,31 +124,6 @@ void event_startup(gboolean reconfig)
 {
     if (reconfig) return;
 
-    mask_table_size = sizeof(mask_table) / sizeof(mask_table[0]);
-     
-    /* get lock masks that are defined by the display (not constant) */
-    modmap = XGetModifierMapping(ob_display);
-    g_assert(modmap);
-    if (modmap && modmap->max_keypermod > 0) {
-        size_t cnt;
-        const size_t size = mask_table_size * modmap->max_keypermod;
-        /* get the values of the keyboard lock modifiers
-           Note: Caps lock is not retrieved the same way as Scroll and Num
-           lock since it doesn't need to be. */
-        const KeyCode num_lock = XKeysymToKeycode(ob_display, XK_Num_Lock);
-        const KeyCode scroll_lock = XKeysymToKeycode(ob_display,
-                                                     XK_Scroll_Lock);
-
-        for (cnt = 0; cnt < size; ++cnt) {
-            if (! modmap->modifiermap[cnt]) continue;
-
-            if (num_lock == modmap->modifiermap[cnt])
-                NumLockMask = mask_table[cnt / modmap->max_keypermod];
-            if (scroll_lock == modmap->modifiermap[cnt])
-                ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
-        }
-    }
-
     ob_main_loop_x_add(ob_main_loop, event_process, NULL, NULL);
 
 #ifdef USE_SM
@@ -179,7 +142,6 @@ void event_shutdown(gboolean reconfig)
 #endif
 
     client_remove_destructor(focus_delay_client_dest);
-    XFreeModifiermap(modmap);
 }
 
 static Window event_get_window(XEvent *e)
@@ -271,54 +233,34 @@ static void event_set_curtime(XEvent *e)
     event_curtime = t;
 }
 
-#define STRIP_MODS(s) \
-        s &= ~(LockMask | NumLockMask | ScrollLockMask), \
-        /* kill off the Button1Mask etc, only want the modifiers */ \
-        s &= (ControlMask | ShiftMask | Mod1Mask | \
-              Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) \
-
 static void event_hack_mods(XEvent *e)
 {
 #ifdef XKB
     XkbStateRec xkb_state;
 #endif
-    KeyCode *kp;
-    gint i, k;
 
     switch (e->type) {
     case ButtonPress:
     case ButtonRelease:
-        STRIP_MODS(e->xbutton.state);
+        e->xbutton.state = modkeys_only_modifier_masks(e->xbutton.state);
         break;
     case KeyPress:
-        STRIP_MODS(e->xkey.state);
+        e->xkey.state = modkeys_only_modifier_masks(e->xkey.state);
         break;
     case KeyRelease:
-        STRIP_MODS(e->xkey.state);
-        /* remove from the state the mask of the modifier being released, if
-           it is a modifier key being released (this is a little ugly..) */
+        e->xkey.state = modkeys_only_modifier_masks(e->xkey.state);
 #ifdef XKB
         if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success) {
             e->xkey.state = xkb_state.compat_state;
             break;
         }
 #endif
-        kp = modmap->modifiermap;
-        for (i = 0; i < mask_table_size; ++i) {
-            for (k = 0; k < modmap->max_keypermod; ++k) {
-                if (*kp == e->xkey.keycode) { /* found the keycode */
-                    /* remove the mask for it */
-                    e->xkey.state &= ~mask_table[i];
-                    /* cause the first loop to break; */
-                    i = mask_table_size;
-                    break; /* get outta here! */
-                }
-                ++kp;
-            }
-        }
+        /* remove from the state the mask of the modifier key being released,
+           if it is a modifier key being released that is */
+        e->xkey.state &= ~modkeys_keycode_to_mask(e->xkey.keycode);
         break;
     case MotionNotify:
-        STRIP_MODS(e->xmotion.state);
+        e->xmotion.state = modkeys_only_modifier_masks(e->xmotion.state);
         /* compress events */
         {
             XEvent ce;
@@ -474,7 +416,23 @@ static void event_process(const XEvent *ec, gpointer data)
         /* crossing events for menu */
         event_handle_menu(e);
     } else if (e->type == FocusIn) {
-        if (client && client != focus_client) {
+        if (e->xfocus.detail == NotifyPointerRoot ||
+            e->xfocus.detail == NotifyDetailNone)
+        {
+            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none\n");
+            /* Focus has been reverted to the root window or nothing.
+               FocusOut events come after UnmapNotify, so we don't need to
+               worry about focusing an invalid window
+             */
+            if (!focus_left_screen)
+                focus_fallback(TRUE);
+        } else if (e->xfocus.detail == NotifyInferior) {
+            ob_debug_type(OB_DEBUG_FOCUS,
+                          "Focus went to root or our frame window");
+            /* Focus has been given to the root window. */
+            focus_fallback(TRUE);
+        } else if (client && client != focus_client) {
+            focus_left_screen = FALSE;
             frame_adjust_focus(client->frame, TRUE);
             focus_set_client(client);
             client_calc_layer(client);
@@ -489,22 +447,28 @@ static void event_process(const XEvent *ec, gpointer data)
         if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) {
             /* There is no FocusIn, this means focus went to a window that
                is not being managed, or a window on another screen. */
-            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n");
+            Window win, root;
+            gint i;
+            guint u;
+            xerror_set_ignore(TRUE);
+            if (XGetInputFocus(ob_display, &win, &i) != 0 &&
+                XGetGeometry(ob_display, win, &root, &i,&i,&u,&u,&u,&u) != 0 &&
+                root != RootWindow(ob_display, ob_screen))
+            {
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "Focus went to another screen !\n");
+                focus_left_screen = TRUE;
+            }
+            else
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "Focus went to a black hole !\n");
+            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 if (ce.xfocus.detail == NotifyPointerRoot ||
-                   ce.xfocus.detail == NotifyDetailNone ||
-                   ce.xfocus.detail == NotifyInferior) {
-            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to root\n");
-            /* Focus has been reverted to the root window or nothing
-               FocusOut events come after UnmapNotify, so we don't need to
-               worry about focusing an invalid window
-             */
-            focus_fallback(TRUE);
         } else {
             /* Focus did move, so process the FocusIn event */
             ObEventData ed = { .ignored = FALSE };
@@ -582,14 +546,16 @@ static void event_process(const XEvent *ec, gpointer data)
         }
 
         if (useevent) {
-            if (!keyboard_process_interactive_grab(e, &client)) {
-                if (moveresize_in_progress) {
-                    moveresize_event(e);
-
+            /* if the keyboard interactive action uses the event then dont
+               use it for bindings. likewise is moveresize uses the event. */
+            if (!keyboard_process_interactive_grab(e, &client) &&
+                !(moveresize_in_progress && moveresize_event(e)))
+            {
+                if (moveresize_in_progress)
                     /* make further actions work on the client being
                        moved/resized */
                     client = moveresize_client;
-                }
+
 
                 menu_can_hide = FALSE;
                 ob_main_loop_timeout_add(ob_main_loop,
@@ -894,6 +860,10 @@ static void event_handle_client(ObClient *client, XEvent *e)
             h = (e->xconfigurerequest.value_mask & CWHeight) ?
                 e->xconfigurerequest.height : client->area.height;
 
+            ob_debug("ConfigureRequest x %d %d y %d %d\n",
+                     e->xconfigurerequest.value_mask & CWX, x,
+                     e->xconfigurerequest.value_mask & CWY, y);
+
             client_find_onscreen(client, &x, &y, w, h, FALSE);
             client_configure_full(client, x, y, w, h, FALSE, TRUE, TRUE);
         }
@@ -1081,6 +1051,9 @@ static void event_handle_client(ObClient *client, XEvent *e)
             else
                 h = client->area.height;
 
+            ob_debug("MOVERESIZE x %d %d y %d %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);
             client_find_onscreen(client, &x, &y, w, h, FALSE);
             client_configure(client, x, y, w, h, FALSE, TRUE);
This page took 0.025342 seconds and 4 git commands to generate.