Fix treatment of input focus on MPX setups
* src/xterm.c (x_ewmh_activate_frame): Use x_set_input_focus instead of XSetInputFocus. (x_set_input_focus): New function. Take into account the ``client pointer'' chosen by Emacs. (x_focus_frame): Use x_set_input_focus instead of XSetInputFocus.
This commit is contained in:
parent
43cca14a9e
commit
fa9777b174
1 changed files with 62 additions and 16 deletions
78
src/xterm.c
78
src/xterm.c
|
@ -1134,6 +1134,7 @@ static void x_clean_failable_requests (struct x_display_info *);
|
|||
static struct frame *x_tooltip_window_to_frame (struct x_display_info *,
|
||||
Window, bool *);
|
||||
static Window x_get_window_below (Display *, Window, int, int, int *, int *);
|
||||
static void x_set_input_focus (struct x_display_info *, Window, Time);
|
||||
|
||||
#ifndef USE_TOOLKIT_SCROLL_BARS
|
||||
static void x_scroll_bar_redraw (struct scroll_bar *);
|
||||
|
@ -27535,11 +27536,10 @@ x_ewmh_activate_frame (struct frame *f)
|
|||
{
|
||||
time = x_get_server_time (f);
|
||||
|
||||
x_ignore_errors_for_next_request (dpyinfo);
|
||||
XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
|
||||
RevertToParent, time);
|
||||
x_set_input_focus (FRAME_DISPLAY_INFO (f),
|
||||
FRAME_OUTER_WINDOW (f),
|
||||
time);
|
||||
XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
|
||||
x_stop_ignoring_errors (dpyinfo);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -27584,6 +27584,57 @@ x_get_toplevel_parent (struct frame *f)
|
|||
return parent;
|
||||
}
|
||||
|
||||
static void
|
||||
x_set_input_focus (struct x_display_info *dpyinfo, Window window,
|
||||
Time time)
|
||||
{
|
||||
#ifdef HAVE_XINPUT2
|
||||
struct xi_device_t *device;
|
||||
#endif
|
||||
|
||||
/* Do the equivalent of XSetInputFocus with the specified window and
|
||||
time, but use the attachment to the device that Emacs has
|
||||
designated the client pointer on X Input Extension builds.
|
||||
Asynchronously trap errors around the generated XI_SetFocus or
|
||||
SetInputFocus request, in case the device has been destroyed or
|
||||
the window obscured.
|
||||
|
||||
The revert_to will be set to RevertToParent for generated
|
||||
SetInputFocus requests. */
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (dpyinfo->supports_xi2
|
||||
&& dpyinfo->client_pointer_device != -1)
|
||||
{
|
||||
device = xi_device_from_id (dpyinfo, dpyinfo->client_pointer_device);
|
||||
|
||||
/* The device is a master pointer. Use its attachment, which
|
||||
should be the master keyboard. */
|
||||
|
||||
if (device)
|
||||
{
|
||||
eassert (device->use == XIMasterPointer);
|
||||
|
||||
x_ignore_errors_for_next_request (dpyinfo);
|
||||
XISetFocus (dpyinfo->display, device->attachment,
|
||||
/* Note that the input extension
|
||||
only supports RevertToParent-type
|
||||
behavior. */
|
||||
window, time);
|
||||
x_stop_ignoring_errors (dpyinfo);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Otherwise, use the pointer device that the X server says is the
|
||||
client pointer. */
|
||||
x_ignore_errors_for_next_request (dpyinfo);
|
||||
XSetInputFocus (dpyinfo->display, window, RevertToParent, time);
|
||||
x_stop_ignoring_errors (dpyinfo);
|
||||
}
|
||||
|
||||
/* In certain situations, when the window manager follows a
|
||||
click-to-focus policy, there seems to be no way around calling
|
||||
XSetInputFocus to give another frame the input focus.
|
||||
|
@ -27653,20 +27704,15 @@ x_focus_frame (struct frame *f, bool noactivate)
|
|||
A BadMatch error can occur if the window was obscured
|
||||
after the time of the last user interaction without
|
||||
changing the last-focus-change-time. */
|
||||
x_ignore_errors_for_next_request (dpyinfo);
|
||||
XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
|
||||
RevertToParent, time);
|
||||
x_stop_ignoring_errors (dpyinfo);
|
||||
x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
|
||||
time);
|
||||
}
|
||||
else
|
||||
{
|
||||
x_ignore_errors_for_next_request (dpyinfo);
|
||||
XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
|
||||
/* But when no window manager is in use, we
|
||||
don't care. */
|
||||
RevertToParent, CurrentTime);
|
||||
x_stop_ignoring_errors (dpyinfo);
|
||||
}
|
||||
x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
|
||||
/* But when no window manager is in use,
|
||||
respecting the ICCCM doesn't really
|
||||
matter. */
|
||||
CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue