summaryrefslogtreecommitdiff
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c373
1 files changed, 252 insertions, 121 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 1e9161c7ab0..e9db4b364fb 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -998,6 +998,7 @@ static const struct x_atom_ref x_atom_refs[] =
ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request)
ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", Xatom_net_wm_sync_request_counter)
ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn)
+ ATOM_REFS_INIT ("_NET_WM_FRAME_TIMINGS", Xatom_net_wm_frame_timings)
ATOM_REFS_INIT ("_NET_WM_USER_TIME", Xatom_net_wm_user_time)
ATOM_REFS_INIT ("_NET_WM_USER_TIME_WINDOW", Xatom_net_wm_user_time_window)
ATOM_REFS_INIT ("_NET_CLIENT_LIST_STACKING", Xatom_net_client_list_stacking)
@@ -1390,6 +1391,12 @@ static int x_dnd_recursion_depth;
initiating Motif drag-and-drop for the first time. */
static Lisp_Object x_dnd_selection_alias_cell;
+/* The last known position of the tooltip window. */
+static int x_dnd_last_tooltip_x, x_dnd_last_tooltip_y;
+
+/* Whether or not those values are actually known yet. */
+static bool x_dnd_last_tooltip_valid;
+
/* Structure describing a single window that can be the target of
drag-and-drop operations. */
struct x_client_list_window
@@ -2931,7 +2938,7 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
Window *toplevels;
int format, rc;
unsigned long nitems, bytes_after;
- unsigned long i;
+ unsigned long i, real_nitems;
unsigned char *data = NULL;
int frame_extents[4];
@@ -2995,6 +3002,16 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
toplevels = (Window *) data;
+ for (i = 0, real_nitems = 0; i < nitems; ++i)
+ {
+ /* Some window managers with built in compositors end up putting
+ tooltips in the client list, which is silly. */
+ if (!x_tooltip_window_to_frame (dpyinfo, toplevels[i], NULL))
+ toplevels[real_nitems++] = toplevels[i];
+ }
+
+ nitems = real_nitems;
+
#ifdef USE_XCB
USE_SAFE_ALLOCA;
@@ -5357,12 +5374,16 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
#endif
}
-/* The code below handles the tracking of scroll valuators on XInput
- 2, in order to support scroll wheels that report information more
- granular than a screen line.
+/* Populate our client-side record of all devices, which includes
+ basic information about the device and also touchscreen tracking
+ information and scroll valuators.
- On X, when the XInput 2 extension is being utilized, the states of
- the mouse wheels in each axis are stored as absolute values inside
+ Keeping track of scroll valuators is required in order to support
+ scroll wheels that report information in a fashion more detailed
+ than a single turn of a "step" in the wheel.
+
+ When the input extension is being utilized, the states of the mouse
+ wheels on each axis are stored as absolute values inside
"valuators" attached to each mouse device. To obtain the delta of
the scroll wheel from a motion event (which is used to report that
some valuator has changed), it is necessary to iterate over every
@@ -5376,20 +5397,13 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
This delta however is still intermediate, to make driver
implementations easier. The XInput developers recommend (and most
programs use) the following algorithm to convert from scroll unit
- deltas to pixel deltas:
+ deltas to pixel deltas by which the display must actually be
+ scrolled:
pixels_scrolled = pow (window_height, 2.0 / 3.0) * delta; */
-/* Setup valuator tracking for XI2 master devices on
- DPYINFO->display. */
-
-/* This function's name is a misnomer: these days, it keeps a
- client-side record of all devices, which includes basic information
- about the device and also touchscreen tracking information, instead
- of just scroll valuators. */
-
static void
-x_init_master_valuators (struct x_display_info *dpyinfo)
+x_cache_xi_devices (struct x_display_info *dpyinfo)
{
int ndevices, actual_devices;
XIDeviceInfo *infos;
@@ -6582,6 +6596,82 @@ x_set_frame_alpha (struct frame *f)
Starting and ending an update
***********************************************************************/
+#if defined HAVE_XSYNC && !defined USE_GTK
+/* Tell the compositing manager to postpone updates of F until a frame
+ has finished drawing. */
+
+static void
+x_sync_update_begin (struct frame *f)
+{
+ XSyncValue value, add;
+ Bool overflow;
+
+ if (FRAME_X_EXTENDED_COUNTER (f) == None)
+ return;
+
+ value = FRAME_X_COUNTER_VALUE (f);
+
+ /* Since a frame is already in progress, there is no point in
+ continuing. */
+ if (XSyncValueLow32 (value) % 2)
+ return;
+
+ /* Since Emacs needs a non-urgent redraw, ensure that value % 4 ==
+ 0. */
+ if (XSyncValueLow32 (value) % 4 == 2)
+ XSyncIntToValue (&add, 3);
+ else
+ XSyncIntToValue (&add, 1);
+
+ XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
+ value, add, &overflow);
+
+ if (XSyncValueLow32 (FRAME_X_COUNTER_VALUE (f)) % 4 != 1)
+ emacs_abort ();
+
+ if (overflow)
+ XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 1);
+
+ XSyncSetCounter (FRAME_X_DISPLAY (f),
+ FRAME_X_EXTENDED_COUNTER (f),
+ FRAME_X_COUNTER_VALUE (f));
+}
+
+/* Tell the compositing manager that FRAME has been drawn and can be
+ updated. */
+
+static void
+x_sync_update_finish (struct frame *f)
+{
+ XSyncValue value, add;
+ Bool overflow;
+
+ if (FRAME_X_EXTENDED_COUNTER (f) == None)
+ return;
+
+ if (FRAME_X_OUTPUT (f)->ext_sync_end_pending_p)
+ return;
+
+ value = FRAME_X_COUNTER_VALUE (f);
+
+ if (!(XSyncValueLow32 (value) % 2))
+ return;
+
+ XSyncIntToValue (&add, 1);
+ XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
+ value, add, &overflow);
+
+ if (overflow)
+ XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 0);
+
+ XSyncSetCounter (FRAME_X_DISPLAY (f),
+ FRAME_X_EXTENDED_COUNTER (f),
+ FRAME_X_COUNTER_VALUE (f));
+
+ /* TODO: implement sync fences. */
+}
+#endif
+
/* Start an update of frame F. This function is installed as a hook
for update_begin, i.e. it is called when update_begin is called.
This function is called prior to calls to gui_update_window_begin for
@@ -6591,7 +6681,11 @@ x_set_frame_alpha (struct frame *f)
static void
x_update_begin (struct frame *f)
{
+#if defined HAVE_XSYNC && !defined USE_GTK
+ x_sync_update_begin (f);
+#else
/* Nothing to do. */
+#endif
}
/* Draw a vertical window border from (x,y0) to (x,y1) */
@@ -6720,7 +6814,10 @@ x_flip_and_flush (struct frame *f)
block_input ();
#ifdef HAVE_XDBE
if (FRAME_X_NEED_BUFFER_FLIP (f))
- show_back_buffer (f);
+ {
+ show_back_buffer (f);
+ x_sync_update_finish (f);
+ }
#endif
x_flush (f);
unblock_input ();
@@ -6737,17 +6834,17 @@ x_update_end (struct frame *f)
#ifdef USE_CAIRO
if (!FRAME_X_DOUBLE_BUFFERED_P (f) && FRAME_CR_CONTEXT (f))
- {
- block_input ();
- cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f)));
- unblock_input ();
- }
+ cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f)));
#endif
-#ifndef XFlush
- block_input ();
- XFlush (FRAME_X_DISPLAY (f));
- unblock_input ();
+ /* If double buffering is disabled, finish the update here.
+ Otherwise, finish the update when the back buffer is next
+ displayed. */
+#if defined HAVE_XSYNC && !defined USE_GTK
+#ifdef HAVE_XDBE
+ if (!FRAME_X_DOUBLE_BUFFERED_P (f))
+#endif
+ x_sync_update_finish (f);
#endif
}
@@ -6775,6 +6872,11 @@ XTframe_up_to_date (struct frame *f)
if (!buffer_flipping_blocked_p ()
&& FRAME_X_NEED_BUFFER_FLIP (f))
show_back_buffer (f);
+
+#if defined HAVE_XSYNC && !defined USE_GTK
+ if (FRAME_X_DOUBLE_BUFFERED_P (f))
+ x_sync_update_finish (f);
+#endif
#endif
#ifdef HAVE_XSYNC
@@ -6791,14 +6893,14 @@ XTframe_up_to_date (struct frame *f)
if (FRAME_X_OUTPUT (f)->ext_sync_end_pending_p
&& FRAME_X_EXTENDED_COUNTER (f) != None)
{
- current = FRAME_X_OUTPUT (f)->current_extended_counter_value;
+ current = FRAME_X_COUNTER_VALUE (f);
if (XSyncValueLow32 (current) % 2)
XSyncIntToValue (&add, 1);
else
XSyncIntToValue (&add, 2);
- XSyncValueAdd (&FRAME_X_OUTPUT (f)->current_extended_counter_value,
+ XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
current, add, &overflow_p);
if (overflow_p)
@@ -6806,7 +6908,7 @@ XTframe_up_to_date (struct frame *f)
XSyncSetCounter (FRAME_X_DISPLAY (f),
FRAME_X_EXTENDED_COUNTER (f),
- FRAME_X_OUTPUT (f)->current_extended_counter_value);
+ FRAME_X_COUNTER_VALUE (f));
FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = false;
}
@@ -11066,7 +11168,8 @@ x_tooltip_window_to_frame (struct x_display_info *dpyinfo,
GdkWindow *tooltip_window;
#endif
- *unrelated_tooltip_p = false;
+ if (unrelated_tooltip_p)
+ *unrelated_tooltip_p = false;
FOR_EACH_FRAME (tail, frame)
{
@@ -11095,14 +11198,16 @@ x_tooltip_window_to_frame (struct x_display_info *dpyinfo,
if (tooltip_window
&& (gdk_x11_window_get_xid (tooltip_window) == wdesc))
{
- *unrelated_tooltip_p = true;
+ if (unrelated_tooltip_p)
+ *unrelated_tooltip_p = true;
break;
}
#else
if (tooltip_window
&& (GDK_WINDOW_XID (tooltip_window) == wdesc))
{
- *unrelated_tooltip_p = true;
+ if (unrelated_tooltip_p)
+ *unrelated_tooltip_p = true;
break;
}
#endif
@@ -11670,6 +11775,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
x_dnd_run_unsupported_drop_function = false;
x_dnd_use_toplevels
= x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_client_list_stacking);
+ x_dnd_last_tooltip_valid = false;
x_dnd_toplevels = NULL;
x_dnd_allow_current_frame = allow_current_frame;
x_dnd_movement_frame = NULL;
@@ -13054,15 +13160,26 @@ static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part,
static Lisp_Object window_being_scrolled;
-/* Whether this is an Xaw with arrow-scrollbars. This should imply
- that movements of 1/20 of the screen size are mapped to up/down. */
+static Time
+x_get_last_toolkit_time (struct x_display_info *dpyinfo)
+{
+#ifdef USE_X_TOOLKIT
+ return XtLastTimestampProcessed (dpyinfo->display);
+#else
+ return dpyinfo->last_user_time;
+#endif
+}
#ifndef USE_GTK
-/* Id of action hook installed for scroll bars. */
+/* Id of action hook installed for scroll bars and horizontal scroll
+ bars. */
static XtActionHookId action_hook_id;
static XtActionHookId horizontal_action_hook_id;
+/* Whether this is an Xaw with arrow-scrollbars. This should imply
+ that movements of 1/20 of the screen size are mapped to up/down. */
+
static Boolean xaw3d_arrow_scroll;
/* Whether the drag scrolling maintains the mouse at the top of the
@@ -13273,12 +13390,8 @@ x_scroll_bar_to_input_event (const XEvent *event,
ievent->kind = SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
ievent->arg = Qnil;
-#ifdef USE_GTK
- ievent->timestamp = CurrentTime;
-#else
- ievent->timestamp =
- XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame)));
-#endif
+ ievent->timestamp
+ = x_get_last_toolkit_time (FRAME_DISPLAY_INFO (XFRAME (w->frame)));
ievent->code = 0;
ievent->part = ev->data.l[2];
ievent->x = make_fixnum (ev->data.l[3]);
@@ -13308,12 +13421,8 @@ x_horizontal_scroll_bar_to_input_event (const XEvent *event,
ievent->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
ievent->arg = Qnil;
-#ifdef USE_GTK
- ievent->timestamp = CurrentTime;
-#else
- ievent->timestamp =
- XtLastTimestampProcessed (FRAME_X_DISPLAY (XFRAME (w->frame)));
-#endif
+ ievent->timestamp
+ = x_get_last_toolkit_time (FRAME_DISPLAY_INFO (XFRAME (w->frame)));
ievent->code = 0;
ievent->part = ev->data.l[2];
ievent->x = make_fixnum (ev->data.l[3]);
@@ -13417,19 +13526,31 @@ xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
bar widget. DATA is a pointer to the scroll_bar structure. */
static gboolean
-xg_scroll_callback (GtkRange *range,
- GtkScrollType scroll,
- gdouble value,
- gpointer user_data)
+xg_scroll_callback (GtkRange *range, GtkScrollType scroll,
+ gdouble value, gpointer user_data)
{
- int whole = 0, portion = 0;
- struct scroll_bar *bar = user_data;
- enum scroll_bar_part part = scroll_bar_nowhere;
- GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
- struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
+ int whole, portion;
+ struct scroll_bar *bar;
+ enum scroll_bar_part part;
+ GtkAdjustment *adj;
+ struct frame *f;
+ guint32 time;
+ struct x_display_info *dpyinfo;
if (xg_ignore_gtk_scrollbar) return false;
+ whole = 0;
+ portion = 0;
+ bar = user_data;
+ part = scroll_bar_nowhere;
+ adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
+ f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
+ time = gtk_get_current_event_time ();
+ dpyinfo = FRAME_DISPLAY_INFO (f);
+
+ if (time != GDK_CURRENT_TIME)
+ x_display_set_last_user_time (dpyinfo, time, true);
+
switch (scroll)
{
case GTK_SCROLL_JUMP:
@@ -13496,8 +13617,11 @@ xg_end_scroll_callback (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
- struct scroll_bar *bar = user_data;
+ struct scroll_bar *bar;
+
+ bar = user_data;
bar->dragging = -1;
+
if (WINDOWP (window_being_scrolled))
{
x_send_scroll_bar_event (window_being_scrolled,
@@ -15910,6 +16034,15 @@ x_dnd_update_tooltip_position (int root_x, int root_y)
x_dnd_compute_tip_xy (&root_x, &root_y,
x_dnd_monitors);
+ if (x_dnd_last_tooltip_valid
+ && root_x == x_dnd_last_tooltip_x
+ && root_y == x_dnd_last_tooltip_y)
+ return;
+
+ x_dnd_last_tooltip_x = root_x;
+ x_dnd_last_tooltip_y = root_y;
+ x_dnd_last_tooltip_valid = true;
+
XMoveWindow (FRAME_X_DISPLAY (x_dnd_frame),
tip_window, root_x, root_y);
}
@@ -16817,8 +16950,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
else if (event->xclient.data.l[4] == 1)
{
- XSyncIntsToValue (&FRAME_X_OUTPUT (f)->current_extended_counter_value,
- event->xclient.data.l[2], event->xclient.data.l[3]);
+ XSyncIntsToValue (&FRAME_X_COUNTER_VALUE (f),
+ event->xclient.data.l[2],
+ event->xclient.data.l[3]);
FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = true;
}
@@ -16935,10 +17069,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
goto done;
}
+#if defined HAVE_XSYNC && !defined USE_GTK
+ /* These messages are sent by the compositing manager after a
+ frame is drawn under extended synchronization. */
+ if (event->xclient.message_type == dpyinfo->Xatom_net_wm_frame_drawn
+ || event->xclient.message_type == dpyinfo->Xatom_net_wm_frame_timings)
+ goto done;
+#endif
+
xft_settings_event (dpyinfo, event);
f = any;
- if (!f)
+ /* We don't want to ever leak tooltip frames to Lisp code. */
+ if (!f || FRAME_TOOLTIP_P (f))
goto OTHER;
/* These values are always used initialized, but GCC doesn't
@@ -17711,7 +17854,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
/* `xkey' will be modified, but it's not important to modify
`event' itself. */
XKeyEvent xkey = event->xkey;
- int i;
+
#ifdef HAVE_XINPUT2
Time pending_keystroke_time;
struct xi_device_t *source;
@@ -17761,27 +17904,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (modifiers & dpyinfo->meta_mod_mask)
memset (&compose_status, 0, sizeof (compose_status));
-#ifdef HAVE_XKB
- if (dpyinfo->xkb_desc)
- {
- XkbDescRec *rec = dpyinfo->xkb_desc;
-
- if (rec->map->modmap && rec->map->modmap[xkey.keycode])
- goto done_keysym;
- }
- else
-#endif
- {
- if (dpyinfo->modmap)
- {
- for (i = 0; i < 8 * dpyinfo->modmap->max_keypermod; i++)
- {
- if (xkey.keycode == dpyinfo->modmap->modifiermap[i])
- goto done_keysym;
- }
- }
- }
-
#ifdef HAVE_X_I18N
if (FRAME_XIC (f))
{
@@ -18258,6 +18380,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
if (f)
{
+ /* Now clear dpyinfo->last_mouse_motion_frame, or
+ gui_redo_mouse_highlight will end up highlighting the
+ last known poisition of the mouse if a tooltip frame is
+ later unmapped. */
+
+ if (f == dpyinfo->last_mouse_motion_frame)
+ dpyinfo->last_mouse_motion_frame = NULL;
+
+ /* Something similar applies to
+ dpyinfo->last_mouse_glyph_frame. */
+ if (f == dpyinfo->last_mouse_glyph_frame)
+ dpyinfo->last_mouse_glyph_frame = NULL;
+
if (f == hlinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
@@ -19004,10 +19139,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
dpyinfo->grabbed |= (1 << event->xbutton.button);
dpyinfo->last_mouse_frame = f;
- if (f && !tab_bar_p)
+
+ if (f)
f->last_tab_bar_item = -1;
#if ! defined (USE_GTK)
- if (f && !tool_bar_p)
+ if (f)
f->last_tool_bar_item = -1;
#endif /* not USE_GTK */
}
@@ -19708,8 +19844,22 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (!f)
f = x_top_window_to_frame (dpyinfo, leave->event);
#endif
+
if (f)
{
+ /* Now clear dpyinfo->last_mouse_motion_frame, or
+ gui_redo_mouse_highlight will end up highlighting
+ the last known poisition of the mouse if a
+ tooltip frame is later unmapped. */
+
+ if (f == dpyinfo->last_mouse_motion_frame)
+ dpyinfo->last_mouse_motion_frame = NULL;
+
+ /* Something similar applies to
+ dpyinfo->last_mouse_glyph_frame. */
+ if (f == dpyinfo->last_mouse_glyph_frame)
+ dpyinfo->last_mouse_glyph_frame = NULL;
+
if (f == hlinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
@@ -19799,9 +19949,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
bar = NULL;
- /* See the comment on top of
- x_init_master_valuators for more details on how
- scroll wheel movement is reported on XInput 2. */
+ /* See the comment on top of x_cache_xi_devices
+ for more details on how scroll wheel movement
+ is reported on XInput 2. */
delta = x_get_scroll_valuator_delta (dpyinfo, device,
i, *values, &val);
values++;
@@ -20407,10 +20557,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (device)
device->grab |= (1 << xev->detail);
- if (f && !tab_bar_p)
+ if (f)
f->last_tab_bar_item = -1;
#if ! defined (USE_GTK)
- if (f && !tool_bar_p)
+ if (f)
f->last_tool_bar_item = -1;
#endif /* not USE_GTK */
}
@@ -21090,27 +21240,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#ifdef HAVE_XKB
if (dpyinfo->xkb_desc)
{
- XkbDescRec *rec = dpyinfo->xkb_desc;
-
- if (rec->map->modmap && rec->map->modmap[xev->detail])
- goto xi_done_keysym;
- }
- else
-#endif
- {
- if (dpyinfo->modmap)
- {
- for (i = 0; i < 8 * dpyinfo->modmap->max_keypermod; i++)
- {
- if (xev->detail == dpyinfo->modmap->modifiermap[i])
- goto xi_done_keysym;
- }
- }
- }
-
-#ifdef HAVE_XKB
- if (dpyinfo->xkb_desc)
- {
uint xkb_state = state;
xkb_state &= ~(1 << 13 | 1 << 14);
xkb_state |= xev->group.effective << 13;
@@ -21663,7 +21792,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (!device)
{
/* An existing device might have been enabled. */
- x_init_master_valuators (dpyinfo);
+ x_cache_xi_devices (dpyinfo);
/* Now try to find the device again, in case it was
just enabled. */
@@ -21795,7 +21924,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xi_find_touch_point (device, xev->detail))
emacs_abort ();
- f = x_any_window_to_frame (dpyinfo, xev->event);
+ f = x_window_to_frame (dpyinfo, xev->event);
#ifdef HAVE_GTK3
menu_bar_p = (f && FRAME_X_OUTPUT (f)->menubar_widget
@@ -21893,7 +22022,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
touchpoint->x = xev->event_x;
touchpoint->y = xev->event_y;
- f = x_any_window_to_frame (dpyinfo, xev->event);
+ f = x_window_to_frame (dpyinfo, xev->event);
if (f && device->direct_p)
{
@@ -21936,7 +22065,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (unlinked_p)
{
- f = x_any_window_to_frame (dpyinfo, xev->event);
+ f = x_window_to_frame (dpyinfo, xev->event);
if (f && device->direct_p)
{
@@ -24291,7 +24420,11 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
#endif
/* 'x_sync_with_move' is too costly for dragging child frames. */
- if (!FRAME_PARENT_FRAME (f))
+ if (!FRAME_PARENT_FRAME (f)
+ /* If no window manager exists, just calling XSync will be
+ sufficient to ensure that the window geometry has been
+ updated. */
+ && NILP (Vx_no_window_manager))
{
x_sync_with_move (f, f->left_pos, f->top_pos,
FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
@@ -25024,11 +25157,9 @@ x_sync_with_move (struct frame *f, int left, int top, bool fuzzy)
current_left = 0;
current_top = 0;
- /* In theory, this call to XSync only needs to happen once, but in
- practice, it doesn't seem to work, hence the need for the surrounding
- loop. */
-
- XSync (FRAME_X_DISPLAY (f), False);
+ /* There is no need to call XSync (even when no window manager
+ is present) because x_real_positions already does that
+ implicitly. */
x_real_positions (f, &current_left, &current_top);
if (fuzzy)
@@ -27290,7 +27421,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
if (rc == Success)
{
dpyinfo->supports_xi2 = true;
- x_init_master_valuators (dpyinfo);
+ x_cache_xi_devices (dpyinfo);
}
}