diff options
| -rw-r--r-- | openbox/actions.c | 20 | ||||
| -rw-r--r-- | openbox/actions.h | 11 | ||||
| -rw-r--r-- | openbox/actions/desktop.c | 2 | ||||
| -rw-r--r-- | openbox/mouse.c | 22 |
4 files changed, 48 insertions, 7 deletions
diff --git a/openbox/actions.c b/openbox/actions.c index a236b581..b7ba5b44 100644 --- a/openbox/actions.c +++ b/openbox/actions.c @@ -23,6 +23,7 @@ #include "event.h" #include "config.h" #include "client.h" +#include "openbox.h" #include "debug.h" #include "actions/all.h" @@ -35,6 +36,7 @@ static ObActionsAct* actions_build_act_from_string(const gchar *name); static ObActionsAct *interactive_act = NULL; static guint interactive_initial_state = 0; +static gboolean replay_pointer = FALSE; struct _ObActionsDefinition { guint ref; @@ -222,6 +224,16 @@ static void actions_setup_data(ObActionsData *data, data->client = client; } +void actions_set_need_pointer_replay_before_move(gboolean replay) +{ + replay_pointer = replay; +} + +gboolean actions_get_need_pointer_replay_before_move() +{ + return replay_pointer; +} + void actions_run_acts(GSList *acts, ObUserAction uact, guint state, @@ -334,8 +346,14 @@ gboolean actions_interactive_input_event(XEvent *e) void actions_client_move(ObActionsData *data, gboolean start) { static gulong ignore_start = 0; - if (start) + if (start) { ignore_start = event_start_ignore_all_enters(); + if (replay_pointer) { + /* replay the pointer event before any windows move */ + XAllowEvents(ob_display, ReplayPointer, event_curtime); + replay_pointer = FALSE; + } + } else if (config_focus_follow && data->context != OB_FRAME_CONTEXT_CLIENT) { diff --git a/openbox/actions.h b/openbox/actions.h index 477e4ba1..6db6f8d6 100644 --- a/openbox/actions.h +++ b/openbox/actions.h @@ -74,9 +74,16 @@ gboolean actions_act_is_interactive(ObActionsAct *act); void actions_act_ref(ObActionsAct *act); void actions_act_unref(ObActionsAct *act); -/*! Pass in a GSList of ObActionsAct's to be run. - @return TRUE if an action is in interactive state, FALSE is none are +/*! When this is true, an XAllowEvents with ReplayPointer will be called + if an action is going to maybe try moving windows around on screen (or + map/unmap windows) */ +void actions_set_need_pointer_replay_before_move(gboolean replay); +/*! Returns if a ReplayPointer is still needed. If it was called while running + actions then this will be false */ +gboolean actions_get_need_pointer_replay_before_move(); + +/*! Pass in a GSList of ObActionsAct's to be run. */ void actions_run_acts(GSList *acts, ObUserAction uact, guint state, diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c index 69275252..d939ed51 100644 --- a/openbox/actions/desktop.c +++ b/openbox/actions/desktop.c @@ -140,12 +140,14 @@ static gboolean run_func(ObActionsData *data, gpointer options) if (d < screen_num_desktops && d != screen_desktop) { gboolean go = TRUE; + actions_client_move(data, TRUE); if (o->send && data->client && client_normal(data->client)) { client_set_desktop(data->client, d, o->follow, FALSE); go = o->follow; } if (go) screen_set_desktop(d, TRUE); + actions_client_move(data, FALSE); } return FALSE; } diff --git a/openbox/mouse.c b/openbox/mouse.c index 66615585..711317ec 100644 --- a/openbox/mouse.c +++ b/openbox/mouse.c @@ -225,6 +225,17 @@ void mouse_event(ObClient *client, XEvent *e) button = e->xbutton.button; state = e->xbutton.state; + /* if the binding was in a client context, then we need to call + XAllowEvents with ReplayPointer at some point, to send the event + through to the client. when this happens though depends. if + windows are going to be moved on screen, then the click will end + up going somewhere wrong, so have the action system perform the + ReplayPointer for us if that is the case. */ + if (CLIENT_CONTEXT(context, client)) + actions_set_need_pointer_replay_before_move(TRUE); + else + actions_set_need_pointer_replay_before_move(FALSE); + fire_binding(OB_MOUSE_ACTION_PRESS, context, client, e->xbutton.state, e->xbutton.button, @@ -235,11 +246,14 @@ void mouse_event(ObClient *client, XEvent *e) if (grab_on_pointer()) button = 0; - if (CLIENT_CONTEXT(context, client)) { - /* Replay the event, so it goes to the client*/ + /* replay the pointer event if it hasn't been replayed yet (i.e. no + windows were moved) */ + if (actions_get_need_pointer_replay_before_move()) XAllowEvents(ob_display, ReplayPointer, event_curtime); - /* Fall through to the release case! */ - } else + + /* in the client context, we won't get a button release because of the + way it is grabbed, so just fake one */ + if (!CLIENT_CONTEXT(context, client)) break; case ButtonRelease: |
