Make a pending ReplayPointer happen before moving/showing/hiding a window in an action.
Commit c907f5af4a
broke kdesktop again, so we have to fix it at an even finer level.
This commit is contained in:
parent
c907f5af4a
commit
38bef0a38b
4 changed files with 41 additions and 25 deletions
|
@ -36,7 +36,6 @@ static ObActionsAct* actions_build_act_from_string(const gchar *name);
|
||||||
|
|
||||||
static ObActionsAct *interactive_act = NULL;
|
static ObActionsAct *interactive_act = NULL;
|
||||||
static guint interactive_initial_state = 0;
|
static guint interactive_initial_state = 0;
|
||||||
static gboolean replay_pointer = FALSE;
|
|
||||||
|
|
||||||
struct _ObActionsDefinition {
|
struct _ObActionsDefinition {
|
||||||
guint ref;
|
guint ref;
|
||||||
|
@ -224,16 +223,6 @@ static void actions_setup_data(ObActionsData *data,
|
||||||
data->client = client;
|
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,
|
void actions_run_acts(GSList *acts,
|
||||||
ObUserAction uact,
|
ObUserAction uact,
|
||||||
guint state,
|
guint state,
|
||||||
|
@ -346,14 +335,8 @@ gboolean actions_interactive_input_event(XEvent *e)
|
||||||
void actions_client_move(ObActionsData *data, gboolean start)
|
void actions_client_move(ObActionsData *data, gboolean start)
|
||||||
{
|
{
|
||||||
static gulong ignore_start = 0;
|
static gulong ignore_start = 0;
|
||||||
if (start) {
|
if (start)
|
||||||
ignore_start = event_start_ignore_all_enters();
|
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 &&
|
else if (config_focus_follow &&
|
||||||
data->context != OB_FRAME_CONTEXT_CLIENT)
|
data->context != OB_FRAME_CONTEXT_CLIENT)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2572,6 +2572,10 @@ gboolean client_show(ObClient *self)
|
||||||
gboolean show = FALSE;
|
gboolean show = FALSE;
|
||||||
|
|
||||||
if (client_should_show(self)) {
|
if (client_should_show(self)) {
|
||||||
|
/* replay pending pointer event before showing the window, in case it
|
||||||
|
should be going to something under the window */
|
||||||
|
mouse_replay_pointer();
|
||||||
|
|
||||||
frame_show(self->frame);
|
frame_show(self->frame);
|
||||||
show = TRUE;
|
show = TRUE;
|
||||||
|
|
||||||
|
@ -2613,6 +2617,10 @@ gboolean client_hide(ObClient *self)
|
||||||
so trying to ignore them is futile in case 3 anyways
|
so trying to ignore them is futile in case 3 anyways
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* replay pending pointer event before hiding the window, in case it
|
||||||
|
should be going to the window */
|
||||||
|
mouse_replay_pointer();
|
||||||
|
|
||||||
frame_hide(self->frame);
|
frame_hide(self->frame);
|
||||||
hide = TRUE;
|
hide = TRUE;
|
||||||
|
|
||||||
|
@ -3028,6 +3036,10 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
|
||||||
if (!user)
|
if (!user)
|
||||||
ignore_start = event_start_ignore_all_enters();
|
ignore_start = event_start_ignore_all_enters();
|
||||||
|
|
||||||
|
/* replay pending pointer event before move the window, in case it
|
||||||
|
would change what window gets the event */
|
||||||
|
mouse_replay_pointer();
|
||||||
|
|
||||||
frame_adjust_area(self->frame, fmoved, fresized, FALSE);
|
frame_adjust_area(self->frame, fmoved, fresized, FALSE);
|
||||||
|
|
||||||
if (!user)
|
if (!user)
|
||||||
|
|
|
@ -46,6 +46,9 @@ typedef struct {
|
||||||
|
|
||||||
/* Array of GSList*s of ObMouseBinding*s. */
|
/* Array of GSList*s of ObMouseBinding*s. */
|
||||||
static GSList *bound_contexts[OB_FRAME_NUM_CONTEXTS];
|
static GSList *bound_contexts[OB_FRAME_NUM_CONTEXTS];
|
||||||
|
/* TRUE when we have a grab on the pointer and need to reply the pointer event
|
||||||
|
to send it to other applications */
|
||||||
|
static gboolean replay_pointer_needed;
|
||||||
|
|
||||||
ObFrameContext mouse_button_frame_context(ObFrameContext context,
|
ObFrameContext mouse_button_frame_context(ObFrameContext context,
|
||||||
guint button,
|
guint button,
|
||||||
|
@ -200,6 +203,15 @@ static gboolean fire_binding(ObMouseAction a, ObFrameContext context,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mouse_replay_pointer()
|
||||||
|
{
|
||||||
|
if (replay_pointer_needed) {
|
||||||
|
/* replay the pointer event before any windows move */
|
||||||
|
XAllowEvents(ob_display, ReplayPointer, event_curtime);
|
||||||
|
replay_pointer_needed = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mouse_event(ObClient *client, XEvent *e)
|
void mouse_event(ObClient *client, XEvent *e)
|
||||||
{
|
{
|
||||||
static Time ltime;
|
static Time ltime;
|
||||||
|
@ -229,12 +241,17 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
XAllowEvents with ReplayPointer at some point, to send the event
|
XAllowEvents with ReplayPointer at some point, to send the event
|
||||||
through to the client. when this happens though depends. if
|
through to the client. when this happens though depends. if
|
||||||
windows are going to be moved on screen, then the click will end
|
windows are going to be moved on screen, then the click will end
|
||||||
up going somewhere wrong, so have the action system perform the
|
up going somewhere wrong, set that we need it, and if nothing
|
||||||
ReplayPointer for us if that is the case. */
|
else causes the replay pointer to be run, then we will do it
|
||||||
|
after all the actions are finished.
|
||||||
|
|
||||||
|
(We do it after all the actions because FocusIn interrupts
|
||||||
|
dragging for kdesktop, so if we send the button event now, and
|
||||||
|
then they get a focus event after, it breaks. Instead, wait to send
|
||||||
|
the button press until after the actions when possible.)
|
||||||
|
*/
|
||||||
if (CLIENT_CONTEXT(context, client))
|
if (CLIENT_CONTEXT(context, client))
|
||||||
actions_set_need_pointer_replay_before_move(TRUE);
|
replay_pointer_needed = TRUE;
|
||||||
else
|
|
||||||
actions_set_need_pointer_replay_before_move(FALSE);
|
|
||||||
|
|
||||||
fire_binding(OB_MOUSE_ACTION_PRESS, context,
|
fire_binding(OB_MOUSE_ACTION_PRESS, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
|
@ -248,8 +265,7 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
|
|
||||||
/* replay the pointer event if it hasn't been replayed yet (i.e. no
|
/* replay the pointer event if it hasn't been replayed yet (i.e. no
|
||||||
windows were moved) */
|
windows were moved) */
|
||||||
if (actions_get_need_pointer_replay_before_move())
|
mouse_replay_pointer();
|
||||||
XAllowEvents(ob_display, ReplayPointer, event_curtime);
|
|
||||||
|
|
||||||
/* in the client context, we won't get a button release because of the
|
/* in the client context, we won't get a button release because of the
|
||||||
way it is grabbed, so just fake one */
|
way it is grabbed, so just fake one */
|
||||||
|
|
|
@ -40,4 +40,9 @@ void mouse_grab_for_client(struct _ObClient *client, gboolean grab);
|
||||||
ObFrameContext mouse_button_frame_context(ObFrameContext context,
|
ObFrameContext mouse_button_frame_context(ObFrameContext context,
|
||||||
guint button, guint state);
|
guint button, guint state);
|
||||||
|
|
||||||
|
/*! If a replay pointer is needed, then do it. Call this when windows are
|
||||||
|
going to be moving/appearing/disappearing, so that you know the mouse click
|
||||||
|
will go to the right window */
|
||||||
|
void mouse_replay_pointer();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue