From 3368b91d544ab8c6510d88e5ad58d070fad62baa Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 8 Jan 2010 10:45:24 -0500 Subject: [PATCH] Don't handle input events on prompts if they should be used for a binding/menu instead. 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 | 59 +++++++++++++++++++++++++--------------------- openbox/keyboard.c | 10 +++++--- openbox/keyboard.h | 2 +- openbox/mouse.c | 46 +++++++++++++++++++----------------- openbox/mouse.h | 2 +- openbox/prompt.c | 27 +++++++++++---------- openbox/prompt.h | 1 + 7 files changed, 81 insertions(+), 66 deletions(-) diff --git a/openbox/event.c b/openbox/event.c index 5127c28f..e279c9db 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -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) diff --git a/openbox/keyboard.c b/openbox/keyboard.c index a342d1ef..5f7531e3 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -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) diff --git a/openbox/keyboard.h b/openbox/keyboard.h index 1674cf92..c89f67e9 100644 --- a/openbox/keyboard.h +++ b/openbox/keyboard.h @@ -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); diff --git a/openbox/mouse.c b/openbox/mouse.c index cd8490f1..ee149354 100644 --- a/openbox/mouse.c +++ b/openbox/mouse.c @@ -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, diff --git a/openbox/mouse.h b/openbox/mouse.h index 2bd5d577..3effcc4d 100644 --- a/openbox/mouse.h +++ b/openbox/mouse.h @@ -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); diff --git a/openbox/prompt.c b/openbox/prompt.c index 829c57f4..4f8930d7 100644 --- a/openbox/prompt.c +++ b/openbox/prompt.c @@ -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; diff --git a/openbox/prompt.h b/openbox/prompt.h index 0d7cfef8..3c46c309 100644 --- a/openbox/prompt.h +++ b/openbox/prompt.h @@ -38,6 +38,7 @@ struct _ObPromptElement { gint x, y, width, height; gboolean pressed; + gboolean hover; gint result; }; -- 2.45.2