]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
new least-intrusive focus stealing prevention
[chaz/openbox] / openbox / event.c
index c6bf6dfe1d55e40a89152373f63c49c0ee2266f3..62778bce829fb6264c0dc22d714409b4f85dbd7b 100644 (file)
@@ -34,7 +34,6 @@
 #include "menuframe.h"
 #include "keyboard.h"
 #include "modkeys.h"
-#include "propwin.h"
 #include "mouse.h"
 #include "mainloop.h"
 #include "focus.h"
@@ -90,7 +89,6 @@ static gboolean event_handle_menu(XEvent *e);
 static void event_handle_dock(ObDock *s, XEvent *e);
 static void event_handle_dockapp(ObDockApp *app, XEvent *e);
 static void event_handle_client(ObClient *c, XEvent *e);
-static void event_handle_user_time_window_clients(GSList *l, XEvent *e);
 static void event_handle_user_input(ObClient *client, XEvent *e);
 static gboolean is_enter_focus_event_ignored(XEvent *e);
 
@@ -99,8 +97,8 @@ static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2);
 static gboolean focus_delay_func(gpointer data);
 static void focus_delay_client_dest(ObClient *client, gpointer data);
 
-/* The time for the current event being processed */
 Time event_curtime = CurrentTime;
+Time event_last_user_time = CurrentTime;
 
 static gboolean focus_left_screen = FALSE;
 /*! A list of ObSerialRanges which are to be ignored for mouse enter events */
@@ -238,15 +236,17 @@ static void event_set_curtime(XEvent *e)
         break;
     }
 
+    /* watch that if we get an event earlier than the last specified user_time,
+       which can happen if the clock goes backwards, we erase the last
+       specified user_time */
+    if (t && event_last_user_time && event_time_after(event_last_user_time, t))
+        event_last_user_time = CurrentTime;
+
     event_curtime = t;
 }
 
 static void event_hack_mods(XEvent *e)
 {
-#ifdef XKB
-    XkbStateRec xkb_state;
-#endif
-
     switch (e->type) {
     case ButtonPress:
     case ButtonRelease:
@@ -257,12 +257,6 @@ static void event_hack_mods(XEvent *e)
         break;
     case KeyRelease:
         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
         /* 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);
@@ -443,7 +437,6 @@ static void event_process(const XEvent *ec, gpointer data)
     ObDock *dock = NULL;
     ObDockApp *dockapp = NULL;
     ObWindow *obwin = NULL;
-    GSList *timewinclients = NULL;
     XEvent ee, *e;
     ObEventData *ed = data;
 
@@ -452,27 +445,24 @@ static void event_process(const XEvent *ec, gpointer data)
     e = ⅇ
 
     window = event_get_window(e);
-    if (e->type != PropertyNotify ||
-        !(timewinclients = propwin_get_clients(window,
-                                               OB_PROPWIN_USER_TIME)))
-        if ((obwin = g_hash_table_lookup(window_map, &window))) {
-            switch (obwin->type) {
-            case Window_Dock:
-                dock = WINDOW_AS_DOCK(obwin);
-                break;
-            case Window_DockApp:
-                dockapp = WINDOW_AS_DOCKAPP(obwin);
-                break;
-            case Window_Client:
-                client = WINDOW_AS_CLIENT(obwin);
-                break;
-            case Window_Menu:
-            case Window_Internal:
-                /* not to be used for events */
-                g_assert_not_reached();
-                break;
-            }
+    if ((obwin = g_hash_table_lookup(window_map, &window))) {
+        switch (obwin->type) {
+        case Window_Dock:
+            dock = WINDOW_AS_DOCK(obwin);
+            break;
+        case Window_DockApp:
+            dockapp = WINDOW_AS_DOCKAPP(obwin);
+            break;
+        case Window_Client:
+            client = WINDOW_AS_CLIENT(obwin);
+            break;
+        case Window_Menu:
+        case Window_Internal:
+            /* not to be used for events */
+            g_assert_not_reached();
+            break;
         }
+    }
 
     event_set_curtime(e);
     event_hack_mods(e);
@@ -617,8 +607,7 @@ static void event_process(const XEvent *ec, gpointer data)
                section or by focus_fallback */
             client_calc_layer(client);
         }
-    } else if (timewinclients)
-        event_handle_user_time_window_clients(timewinclients, e);
+    }
     else if (client)
         event_handle_client(client, e);
     else if (dockapp)
@@ -776,15 +765,6 @@ void event_enter_client(ObClient *client)
     }
 }
 
-static void event_handle_user_time_window_clients(GSList *l, XEvent *e)
-{
-    g_assert(e->type == PropertyNotify);
-    if (e->xproperty.atom == prop_atoms.net_wm_user_time) {
-        for (; l; l = g_slist_next(l))
-            client_update_user_time(l->data);
-    }
-}
-
 static void event_handle_client(ObClient *client, XEvent *e)
 {
     XEvent ce;
@@ -1298,8 +1278,11 @@ static void event_handle_client(ObClient *client, XEvent *e)
                        (e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
             /* XXX make use of data.l[2] !? */
             if (e->xclient.data.l[0] == 1 || e->xclient.data.l[0] == 2) {
-                event_curtime = e->xclient.data.l[1];
-                if (event_curtime == 0)
+                /* don't use the user's timestamp for client_focus, cuz if it's
+                   an old broken timestamp (happens all the time) then focus
+                   won't move even though we're trying to move it
+                  event_curtime = e->xclient.data.l[1];*/
+                if (e->xclient.data.l[1] == 0)
                     ob_debug_type(OB_DEBUG_APP_BUGS,
                                   "_NET_ACTIVE_WINDOW message for window %s is"
                                   " missing a timestamp\n", client->title);
@@ -1520,10 +1503,14 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_update_icon_geometry(client);
         }
         else if (msgtype == prop_atoms.net_wm_user_time) {
-            client_update_user_time(client);
-        }
-        else if (msgtype == prop_atoms.net_wm_user_time_window) {
-            client_update_user_time_window(client);
+            guint32 t;
+            if (PROP_GET32(client->window, net_wm_user_time, cardinal, &t) &&
+                t && !event_time_after(t, e->xproperty.time) &&
+                (!event_last_user_time ||
+                 event_time_after(t, event_last_user_time)))
+            {
+                event_last_user_time = t;
+            }
         }
 #ifdef SYNC
         else if (msgtype == prop_atoms.net_wm_sync_request_counter) {
@@ -1927,6 +1914,10 @@ void event_cancel_all_key_grabs()
         menu_frame_hide_all();
         ob_debug("KILLED open menus\n");
     }
+    else if (moveresize_in_progress) {
+        moveresize_end(TRUE);
+        ob_debug("KILLED interactive moveresize\n");
+    }
     else if (grab_on_keyboard()) {
         ungrab_keyboard();
         ob_debug("KILLED active grab on keyboard\n");
@@ -1959,3 +1950,15 @@ gboolean event_time_after(Time t1, Time t2)
         /* t2 is in the first half so t1 has to come after it */
         return t1 >= t2 && t1 < (t2 + TIME_HALF);
 }
+
+Time event_get_server_time()
+{
+    /* Generate a timestamp */
+    XEvent event;
+
+    XChangeProperty(ob_display, screen_support_win,
+                    prop_atoms.wm_class, prop_atoms.string,
+                    8, PropModeAppend, NULL, 0);
+    XWindowEvent(ob_display, screen_support_win, PropertyChangeMask, &event);
+    return event.xproperty.time;
+}
This page took 0.02505 seconds and 4 git commands to generate.