Don't handle input events on prompts if they should be used for a binding/menu instead.
authorDana Jansens <danakj@orodu.net>
Fri, 8 Jan 2010 15:45:24 +0000 (10:45 -0500)
committerDana Jansens <danakj@orodu.net>
Fri, 8 Jan 2010 15:45:24 +0000 (10:45 -0500)
Also, be more careful about making the prompt buttons look pressed, don't make them pressed from a motion notify event if they didnt first handle the press.

openbox/event.c
openbox/keyboard.c
openbox/keyboard.h
openbox/mouse.c
openbox/mouse.h
openbox/prompt.c
openbox/prompt.h

index 5127c28..e279c9d 100644 (file)
@@ -90,7 +90,7 @@ static gboolean event_handle_prompt(ObPrompt *p, 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_input(ObClient *client, XEvent *e);
+static gboolean event_handle_user_input(ObClient *client, XEvent *e);
 static gboolean is_enter_focus_event_ignored(gulong serial);
 static void event_ignore_enter_range(gulong start, gulong end);
 
@@ -472,6 +472,7 @@ static void event_process(const XEvent *ec, gpointer data)
     ObWindow *obwin = NULL;
     ObMenuFrame *menu = NULL;
     ObPrompt *prompt = NULL;
+    gboolean used;
 
     /* make a copy we can mangle */
     ee = *ec;
@@ -717,15 +718,13 @@ static void event_process(const XEvent *ec, gpointer data)
     }
 #endif
 
-    if (prompt && event_handle_prompt(prompt, e))
-        ;
-    else if (e->type == ButtonPress || e->type == ButtonRelease) {
+    if (e->type == ButtonPress || e->type == ButtonRelease) {
         /* If the button press was on some non-root window, or was physically
            on the root window, then process it */
         if (window != obt_root(ob_screen) ||
             e->xbutton.subwindow == None)
         {
-            event_handle_user_input(client, e);
+            used = event_handle_user_input(client, e);
         }
         /* Otherwise only process it if it was physically on an openbox
            internal window */
@@ -735,13 +734,16 @@ static void event_process(const XEvent *ec, gpointer data)
             if ((w = window_find(e->xbutton.subwindow)) &&
                 WINDOW_IS_INTERNAL(w))
             {
-                event_handle_user_input(client, e);
+                used = event_handle_user_input(client, e);
             }
         }
     }
     else if (e->type == KeyPress || e->type == KeyRelease ||
              e->type == MotionNotify)
-        event_handle_user_input(client, e);
+        used = event_handle_user_input(client, e);
+
+    if (prompt && !used)
+        used = event_handle_prompt(prompt, e);
 
     /* if something happens and it's not from an XEvent, then we don't know
        the time */
@@ -1955,7 +1957,7 @@ static void event_handle_menu(ObMenuFrame *frame, XEvent *ev)
     }
 }
 
-static void event_handle_user_input(ObClient *client, XEvent *e)
+static gboolean event_handle_user_input(ObClient *client, XEvent *e)
 {
     g_assert(e->type == ButtonPress || e->type == ButtonRelease ||
              e->type == MotionNotify || e->type == KeyPress ||
@@ -1966,29 +1968,32 @@ static void event_handle_user_input(ObClient *client, XEvent *e)
             /* don't use the event if the menu used it, but if the menu
                didn't use it and it's a keypress that is bound, it will
                close the menu and be used */
-            return;
+            return TRUE;
     }
 
     /* if the keyboard interactive action uses the event then dont
        use it for bindings. likewise is moveresize uses the event. */
-    if (!actions_interactive_input_event(e) && !moveresize_event(e)) {
-        if (moveresize_in_progress)
-            /* make further actions work on the client being
-               moved/resized */
-            client = moveresize_client;
-
-        if (e->type == ButtonPress ||
-            e->type == ButtonRelease ||
-            e->type == MotionNotify)
-        {
-            /* the frame may not be "visible" but they can still click on it
-               in the case where it is animating before disappearing */
-            if (!client || !frame_iconify_animating(client->frame))
-                mouse_event(client, e);
-        } else
-            keyboard_event((focus_cycle_target ? focus_cycle_target :
-                            (client ? client : focus_client)), e);
-    }
+    if (actions_interactive_input_event(e) || moveresize_event(e))
+        return TRUE;
+
+    if (moveresize_in_progress)
+        /* make further actions work on the client being
+           moved/resized */
+        client = moveresize_client;
+
+    if (e->type == ButtonPress ||
+        e->type == ButtonRelease ||
+        e->type == MotionNotify)
+    {
+        /* the frame may not be "visible" but they can still click on it
+           in the case where it is animating before disappearing */
+        if (!client || !frame_iconify_animating(client->frame))
+            return mouse_event(client, e);
+    } else
+        return keyboard_event((focus_cycle_target ? focus_cycle_target :
+                               (client ? client : focus_client)), e);
+
+    return FALSE;
 }
 
 static void focus_delay_dest(gpointer data)
index a342d1e..5f7531e 100644 (file)
@@ -204,13 +204,14 @@ gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client)
 }
 #endif
 
-void keyboard_event(ObClient *client, const XEvent *e)
+gboolean keyboard_event(ObClient *client, const XEvent *e)
 {
     KeyBindingTree *p;
+    gboolean used;
 
     if (e->type == KeyRelease) {
         grab_key_passive_count(-1);
-        return;
+        return FALSE;
     }
 
     g_assert(e->type == KeyPress);
@@ -221,9 +222,10 @@ void keyboard_event(ObClient *client, const XEvent *e)
     {
         obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
         keyboard_reset_chains(-1);
-        return;
+        return TRUE;
     }
 
+    used = FALSE;
     if (curpos == NULL)
         p = keyboard_firstnode;
     else
@@ -258,9 +260,11 @@ void keyboard_event(ObClient *client, const XEvent *e)
                                  0, OB_FRAME_CONTEXT_NONE, client);
             }
             break;
+            used = TRUE;
         }
         p = p->next_sibling;
     }
+    return used;
 }
 
 static void node_rebind(KeyBindingTree *node)
index 1674cf9..c89f67e 100644 (file)
@@ -40,7 +40,7 @@ void keyboard_chroot(GList *keylist);
 gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action);
 void keyboard_unbind_all(void);
 
-void keyboard_event(struct _ObClient *client, const XEvent *e);
+gboolean keyboard_event(struct _ObClient *client, const XEvent *e);
 /*! @param break_chroots how many chroots to break. -1 means to break them ALL!
  */
 void keyboard_reset_chains(gint break_chroots);
index cd8490f..ee14935 100644 (file)
@@ -205,12 +205,13 @@ void mouse_replay_pointer(void)
     }
 }
 
-void mouse_event(ObClient *client, XEvent *e)
+gboolean mouse_event(ObClient *client, XEvent *e)
 {
     static Time ltime;
     static guint button = 0, state = 0, lbutton = 0;
     static Window lwindow = None;
     static gint px, py, pwx = -1, pwy = -1;
+    gboolean used = FALSE;
 
     ObFrameContext context;
     gboolean click = FALSE;
@@ -246,10 +247,10 @@ void mouse_event(ObClient *client, XEvent *e)
         if (CLIENT_CONTEXT(context, client))
             replay_pointer_needed = TRUE;
 
-        fire_binding(OB_MOUSE_ACTION_PRESS, context,
-                     client, e->xbutton.state,
-                     e->xbutton.button,
-                     e->xbutton.x_root, e->xbutton.y_root);
+        used = fire_binding(OB_MOUSE_ACTION_PRESS, context,
+                            client, e->xbutton.state,
+                            e->xbutton.button,
+                            e->xbutton.x_root, e->xbutton.y_root) || used;
 
         /* if the bindings grab the pointer, there won't be a ButtonRelease
            event for us */
@@ -311,23 +312,23 @@ void mouse_event(ObClient *client, XEvent *e)
             state = 0;
             ltime = e->xbutton.time;
         }
-        fire_binding(OB_MOUSE_ACTION_RELEASE, context,
-                     client, e->xbutton.state,
-                     e->xbutton.button,
-                     e->xbutton.x_root,
-                     e->xbutton.y_root);
+        used = fire_binding(OB_MOUSE_ACTION_RELEASE, context,
+                            client, e->xbutton.state,
+                            e->xbutton.button,
+                            e->xbutton.x_root,
+                            e->xbutton.y_root) || used;
         if (click)
-            fire_binding(OB_MOUSE_ACTION_CLICK, context,
-                         client, e->xbutton.state,
-                         e->xbutton.button,
-                         e->xbutton.x_root,
-                         e->xbutton.y_root);
+            used = fire_binding(OB_MOUSE_ACTION_CLICK, context,
+                                client, e->xbutton.state,
+                                e->xbutton.button,
+                                e->xbutton.x_root,
+                                e->xbutton.y_root) || used;
         if (dclick)
-            fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
-                         client, e->xbutton.state,
-                         e->xbutton.button,
-                         e->xbutton.x_root,
-                         e->xbutton.y_root);
+            used = fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
+                                client, e->xbutton.state,
+                                e->xbutton.button,
+                                e->xbutton.x_root,
+                                e->xbutton.y_root) || used;
         break;
 
     case MotionNotify:
@@ -347,8 +348,8 @@ void mouse_event(ObClient *client, XEvent *e)
                     context == OB_FRAME_CONTEXT_CLOSE)
                     break;
 
-                fire_binding(OB_MOUSE_ACTION_MOTION, context,
-                             client, state, button, px, py);
+                used = fire_binding(OB_MOUSE_ACTION_MOTION, context,
+                                    client, state, button, px, py);
                 button = 0;
                 state = 0;
             }
@@ -358,6 +359,7 @@ void mouse_event(ObClient *client, XEvent *e)
     default:
         g_assert_not_reached();
     }
+    return used;
 }
 
 gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,
index 2bd5d57..3effcc4 100644 (file)
@@ -33,7 +33,7 @@ gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,
                     ObMouseAction mact, struct _ObActionsAct *action);
 void mouse_unbind_all(void);
 
-void mouse_event(struct _ObClient *client, XEvent *e);
+gboolean mouse_event(struct _ObClient *client, XEvent *e);
 
 void mouse_grab_for_client(struct _ObClient *client, gboolean grab);
 
index 829c57f..4f8930d 100644 (file)
@@ -411,10 +411,10 @@ static void render_button(ObPrompt *self, ObPromptElement *e)
 {
     RrAppearance *a;
 
-    if (e->pressed && self->focus == e) a = prompt_a_pfocus;
-    else if (self->focus == e)          a = prompt_a_focus;
-    else if (e->pressed)                a = prompt_a_press;
-    else                                a = prompt_a_button;
+    if (e->hover && self->focus == e) a = prompt_a_pfocus;
+    else if (self->focus == e)        a = prompt_a_focus;
+    else if (e->pressed)              a = prompt_a_press;
+    else                              a = prompt_a_button;
 
     a->surface.parent = prompt_a_bg;
     a->surface.parentx = e->x;
@@ -587,25 +587,28 @@ gboolean prompt_mouse_event(ObPrompt *self, XEvent *e)
 
         oldfocus = self->focus;
 
-        but->pressed = TRUE;
+        but->pressed = but->hover = TRUE;
         self->focus = but;
 
         if (oldfocus != but) render_button(self, oldfocus);
         render_button(self, but);
     }
     else if (e->type == ButtonRelease) {
-        if (but->pressed)
+        if (but->hover)
             prompt_run_callback(self, but->result);
+        but->pressed = FALSE;
     }
     else if (e->type == MotionNotify) {
-        gboolean press;
+        if (but->pressed) {
+            gboolean hover;
 
-        press = (e->xmotion.x >= 0 && e->xmotion.y >= 0 &&
-                 e->xmotion.x < but->width && e->xmotion.y < but->height);
+            hover = (e->xmotion.x >= 0 && e->xmotion.y >= 0 &&
+                     e->xmotion.x < but->width && e->xmotion.y < but->height);
 
-        if (press != but->pressed) {
-            but->pressed = press;
-            render_button(self, but);
+            if (hover != but->hover) {
+                but->hover = hover;
+                render_button(self, but);
+            }
         }
     }
     return TRUE;
index 0d7cfef..3c46c30 100644 (file)
@@ -38,6 +38,7 @@ struct _ObPromptElement {
 
     gint x, y, width, height;
     gboolean pressed;
+    gboolean hover;
     gint result;
 };