mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 18:11:05 -05:00
window: Throttle resize-grab updates to stage updates
With high frequency mouse devices, we would send very many configure events per each update cycle, which had the end result that some clients constantly re-allocating and redrawing their buffers far too often, if they did this in direct response to xdg_toplevel configure events. Lets throttle the interactive resize updates to stage updates, to avoid having these clients doing the excessive buffer reallocation. This also removes some old legacy X11 client resize throttling, that throttled a bit arbitrarily on 25 resizes a second; it is probably enough to throttle on stage updates for these clients. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2652>
This commit is contained in:
parent
5fa1a8cf42
commit
11a50fffa2
@ -183,11 +183,9 @@ struct _MetaDisplay
|
|||||||
MetaRectangle grab_initial_window_pos;
|
MetaRectangle grab_initial_window_pos;
|
||||||
int grab_initial_x, grab_initial_y; /* These are only relevant for */
|
int grab_initial_x, grab_initial_y; /* These are only relevant for */
|
||||||
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
|
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
|
||||||
int64_t grab_last_moveresize_time;
|
|
||||||
MetaEdgeResistanceData *grab_edge_resistance_data;
|
MetaEdgeResistanceData *grab_edge_resistance_data;
|
||||||
unsigned int grab_last_edge_resistance_flags;
|
unsigned int grab_last_edge_resistance_flags;
|
||||||
|
unsigned int grab_move_resize_later_id;
|
||||||
int grab_resize_timeout_id;
|
|
||||||
|
|
||||||
MetaKeyBindingManager key_binding_manager;
|
MetaKeyBindingManager key_binding_manager;
|
||||||
|
|
||||||
@ -342,6 +340,8 @@ gboolean meta_grab_op_is_resizing (MetaGrabOp op);
|
|||||||
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
|
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
|
||||||
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
|
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
|
||||||
|
|
||||||
|
void meta_display_clear_grab_move_resize_later (MetaDisplay *display);
|
||||||
|
|
||||||
void meta_display_queue_autoraise_callback (MetaDisplay *display,
|
void meta_display_queue_autoraise_callback (MetaDisplay *display,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
void meta_display_remove_autoraise_callback (MetaDisplay *display);
|
void meta_display_remove_autoraise_callback (MetaDisplay *display);
|
||||||
|
@ -878,7 +878,6 @@ meta_display_new (MetaContext *context,
|
|||||||
|
|
||||||
display->current_time = META_CURRENT_TIME;
|
display->current_time = META_CURRENT_TIME;
|
||||||
|
|
||||||
display->grab_resize_timeout_id = 0;
|
|
||||||
display->grab_have_keyboard = FALSE;
|
display->grab_have_keyboard = FALSE;
|
||||||
|
|
||||||
display->grab_op = META_GRAB_OP_NONE;
|
display->grab_op = META_GRAB_OP_NONE;
|
||||||
@ -1849,6 +1848,21 @@ get_event_route_from_grab_op (MetaGrabOp op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_clear_grab_move_resize_later (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
if (display->grab_move_resize_later_id)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor;
|
||||||
|
MetaLaters *laters;
|
||||||
|
|
||||||
|
compositor = meta_display_get_compositor (display);
|
||||||
|
laters = meta_compositor_get_laters (compositor);
|
||||||
|
meta_laters_remove (laters, display->grab_move_resize_later_id);
|
||||||
|
display->grab_move_resize_later_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_display_begin_grab_op (MetaDisplay *display,
|
meta_display_begin_grab_op (MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
@ -1955,13 +1969,12 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
|||||||
display->grab_anchor_root_y = root_y;
|
display->grab_anchor_root_y = root_y;
|
||||||
display->grab_latest_motion_x = root_x;
|
display->grab_latest_motion_x = root_x;
|
||||||
display->grab_latest_motion_y = root_y;
|
display->grab_latest_motion_y = root_y;
|
||||||
display->grab_last_moveresize_time = 0;
|
|
||||||
display->grab_last_edge_resistance_flags = META_EDGE_RESISTANCE_DEFAULT;
|
display->grab_last_edge_resistance_flags = META_EDGE_RESISTANCE_DEFAULT;
|
||||||
display->grab_frame_action = frame_action;
|
display->grab_frame_action = frame_action;
|
||||||
|
|
||||||
meta_display_update_cursor (display);
|
meta_display_update_cursor (display);
|
||||||
|
|
||||||
g_clear_handle_id (&display->grab_resize_timeout_id, g_source_remove);
|
meta_display_clear_grab_move_resize_later (display);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||||
"Grab op %u on window %s successful",
|
"Grab op %u on window %s successful",
|
||||||
@ -2046,13 +2059,12 @@ meta_display_end_grab_op (MetaDisplay *display,
|
|||||||
display->grab_anchor_root_y = 0;
|
display->grab_anchor_root_y = 0;
|
||||||
display->grab_latest_motion_x = 0;
|
display->grab_latest_motion_x = 0;
|
||||||
display->grab_latest_motion_y = 0;
|
display->grab_latest_motion_y = 0;
|
||||||
display->grab_last_moveresize_time = 0;
|
|
||||||
display->grab_last_edge_resistance_flags = META_EDGE_RESISTANCE_DEFAULT;
|
display->grab_last_edge_resistance_flags = META_EDGE_RESISTANCE_DEFAULT;
|
||||||
display->grab_frame_action = FALSE;
|
display->grab_frame_action = FALSE;
|
||||||
|
|
||||||
meta_display_update_cursor (display);
|
meta_display_update_cursor (display);
|
||||||
|
|
||||||
g_clear_handle_id (&display->grab_resize_timeout_id, g_source_remove);
|
meta_display_clear_grab_move_resize_later (display);
|
||||||
|
|
||||||
if (meta_is_wayland_compositor ())
|
if (meta_is_wayland_compositor ())
|
||||||
meta_display_sync_wayland_input_focus (display);
|
meta_display_sync_wayland_input_focus (display);
|
||||||
|
@ -867,8 +867,8 @@ void meta_window_set_urgent (MetaWindow *window,
|
|||||||
|
|
||||||
void meta_window_update_resize (MetaWindow *window,
|
void meta_window_update_resize (MetaWindow *window,
|
||||||
MetaEdgeResistanceFlags flags,
|
MetaEdgeResistanceFlags flags,
|
||||||
int x, int y,
|
int x,
|
||||||
gboolean force);
|
int y);
|
||||||
|
|
||||||
void meta_window_move_resize_internal (MetaWindow *window,
|
void meta_window_move_resize_internal (MetaWindow *window,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
|
@ -136,11 +136,6 @@ static void update_move (MetaWindow *window,
|
|||||||
MetaEdgeResistanceFlags flags,
|
MetaEdgeResistanceFlags flags,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
static void update_resize (MetaWindow *window,
|
|
||||||
MetaEdgeResistanceFlags flags,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
gboolean force);
|
|
||||||
static gboolean should_be_on_all_workspaces (MetaWindow *window);
|
static gboolean should_be_on_all_workspaces (MetaWindow *window);
|
||||||
|
|
||||||
static void meta_window_flush_calc_showing (MetaWindow *window);
|
static void meta_window_flush_calc_showing (MetaWindow *window);
|
||||||
@ -5765,44 +5760,6 @@ meta_window_titlebar_is_onscreen (MetaWindow *window)
|
|||||||
return is_onscreen;
|
return is_onscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
check_moveresize_frequency (MetaWindow *window,
|
|
||||||
gdouble *remaining)
|
|
||||||
{
|
|
||||||
int64_t current_time;
|
|
||||||
const double max_resizes_per_second = 25.0;
|
|
||||||
const double ms_between_resizes = 1000.0 / max_resizes_per_second;
|
|
||||||
double elapsed;
|
|
||||||
|
|
||||||
current_time = g_get_real_time ();
|
|
||||||
|
|
||||||
/* If we are throttling via _NET_WM_SYNC_REQUEST, we don't need
|
|
||||||
* an artificial timeout-based throttled */
|
|
||||||
if (!window->disable_sync &&
|
|
||||||
window->sync_request_alarm != None)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
elapsed = (current_time - window->display->grab_last_moveresize_time) / 1000;
|
|
||||||
|
|
||||||
if (elapsed >= 0.0 && elapsed < ms_between_resizes)
|
|
||||||
{
|
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
|
||||||
"Delaying move/resize as only %g of %g ms elapsed",
|
|
||||||
elapsed, ms_between_resizes);
|
|
||||||
|
|
||||||
if (remaining)
|
|
||||||
*remaining = (ms_between_resizes - elapsed);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta_topic (META_DEBUG_RESIZING,
|
|
||||||
" Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)",
|
|
||||||
elapsed / 1000.0, 1.0 / max_resizes_per_second);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_move_maybe_tile (MetaWindow *window,
|
update_move_maybe_tile (MetaWindow *window,
|
||||||
int shake_threshold,
|
int shake_threshold,
|
||||||
@ -6042,35 +5999,22 @@ update_move (MetaWindow *window,
|
|||||||
meta_window_move_frame (window, TRUE, new_x, new_y);
|
meta_window_move_frame (window, TRUE, new_x, new_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
update_resize_timeout (gpointer data)
|
|
||||||
{
|
|
||||||
MetaWindow *window = data;
|
|
||||||
|
|
||||||
update_resize (window,
|
|
||||||
window->display->grab_last_edge_resistance_flags,
|
|
||||||
window->display->grab_latest_motion_x,
|
|
||||||
window->display->grab_latest_motion_y,
|
|
||||||
TRUE);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_resize (MetaWindow *window,
|
update_resize (MetaWindow *window,
|
||||||
MetaEdgeResistanceFlags flags,
|
MetaEdgeResistanceFlags flags,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y)
|
||||||
gboolean force)
|
|
||||||
{
|
{
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
MetaGravity gravity;
|
MetaGravity gravity;
|
||||||
MetaRectangle new_rect;
|
MetaRectangle new_rect;
|
||||||
MetaRectangle old_rect;
|
MetaRectangle old_rect;
|
||||||
double remaining = 0;
|
|
||||||
|
|
||||||
window->display->grab_latest_motion_x = x;
|
window->display->grab_latest_motion_x = x;
|
||||||
window->display->grab_latest_motion_y = y;
|
window->display->grab_latest_motion_y = y;
|
||||||
|
|
||||||
|
meta_display_clear_grab_move_resize_later (window->display);
|
||||||
|
|
||||||
dx = x - window->display->grab_anchor_root_x;
|
dx = x - window->display->grab_anchor_root_x;
|
||||||
dy = y - window->display->grab_anchor_root_y;
|
dy = y - window->display->grab_anchor_root_y;
|
||||||
|
|
||||||
@ -6132,27 +6076,6 @@ update_resize (MetaWindow *window,
|
|||||||
if (window->sync_request_timeout_id != 0)
|
if (window->sync_request_timeout_id != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!check_moveresize_frequency (window, &remaining) && !force)
|
|
||||||
{
|
|
||||||
/* we are ignoring an event here, so we schedule a
|
|
||||||
* compensation event when we would otherwise not ignore
|
|
||||||
* an event. Otherwise we can become stuck if the user never
|
|
||||||
* generates another event.
|
|
||||||
*/
|
|
||||||
if (!window->display->grab_resize_timeout_id)
|
|
||||||
{
|
|
||||||
window->display->grab_resize_timeout_id =
|
|
||||||
g_timeout_add ((int)remaining, update_resize_timeout, window);
|
|
||||||
g_source_set_name_by_id (window->display->grab_resize_timeout_id,
|
|
||||||
"[mutter] update_resize_timeout");
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove any scheduled compensation events */
|
|
||||||
g_clear_handle_id (&window->display->grab_resize_timeout_id, g_source_remove);
|
|
||||||
|
|
||||||
meta_window_get_frame_rect (window, &old_rect);
|
meta_window_get_frame_rect (window, &old_rect);
|
||||||
|
|
||||||
/* One sided resizing ought to actually be one-sided, despite the fact that
|
/* One sided resizing ought to actually be one-sided, despite the fact that
|
||||||
@ -6180,11 +6103,45 @@ update_resize (MetaWindow *window,
|
|||||||
meta_window_resize_frame_with_gravity (window, TRUE,
|
meta_window_resize_frame_with_gravity (window, TRUE,
|
||||||
new_rect.width, new_rect.height,
|
new_rect.width, new_rect.height,
|
||||||
gravity);
|
gravity);
|
||||||
|
}
|
||||||
|
|
||||||
/* Store the latest resize time, if we actually resized. */
|
static gboolean
|
||||||
if (window->rect.width != old_rect.width ||
|
update_resize_cb (gpointer user_data)
|
||||||
window->rect.height != old_rect.height)
|
{
|
||||||
window->display->grab_last_moveresize_time = g_get_real_time ();
|
MetaWindow *window = user_data;
|
||||||
|
|
||||||
|
window->display->grab_move_resize_later_id = 0;
|
||||||
|
|
||||||
|
update_resize (window,
|
||||||
|
window->display->grab_last_edge_resistance_flags,
|
||||||
|
window->display->grab_latest_motion_x,
|
||||||
|
window->display->grab_latest_motion_y);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
queue_update_resize (MetaWindow *window,
|
||||||
|
MetaEdgeResistanceFlags flags,
|
||||||
|
int x,
|
||||||
|
int y)
|
||||||
|
{
|
||||||
|
MetaCompositor *compositor;
|
||||||
|
MetaLaters *laters;
|
||||||
|
|
||||||
|
window->display->grab_latest_motion_x = x;
|
||||||
|
window->display->grab_latest_motion_y = y;
|
||||||
|
|
||||||
|
if (window->display->grab_move_resize_later_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
compositor = meta_display_get_compositor (window->display);
|
||||||
|
laters = meta_compositor_get_laters (compositor);
|
||||||
|
window->display->grab_move_resize_later_id =
|
||||||
|
meta_laters_add (laters,
|
||||||
|
META_LATER_BEFORE_REDRAW,
|
||||||
|
update_resize_cb,
|
||||||
|
window, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -6208,10 +6165,9 @@ maybe_maximize_tiled_window (MetaWindow *window)
|
|||||||
void
|
void
|
||||||
meta_window_update_resize (MetaWindow *window,
|
meta_window_update_resize (MetaWindow *window,
|
||||||
MetaEdgeResistanceFlags flags,
|
MetaEdgeResistanceFlags flags,
|
||||||
int x, int y,
|
int x, int y)
|
||||||
gboolean force)
|
|
||||||
{
|
{
|
||||||
update_resize (window, flags, x, y, force);
|
update_resize (window, flags, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -6255,7 +6211,7 @@ end_grab_op (MetaWindow *window,
|
|||||||
if (window->tile_match != NULL)
|
if (window->tile_match != NULL)
|
||||||
flags |= (META_EDGE_RESISTANCE_SNAP | META_EDGE_RESISTANCE_WINDOWS);
|
flags |= (META_EDGE_RESISTANCE_SNAP | META_EDGE_RESISTANCE_WINDOWS);
|
||||||
|
|
||||||
update_resize (window, flags, x, y, TRUE);
|
update_resize (window, flags, x, y);
|
||||||
maybe_maximize_tiled_window (window);
|
maybe_maximize_tiled_window (window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6339,7 +6295,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
if (window->tile_match != NULL)
|
if (window->tile_match != NULL)
|
||||||
flags |= (META_EDGE_RESISTANCE_SNAP | META_EDGE_RESISTANCE_WINDOWS);
|
flags |= (META_EDGE_RESISTANCE_SNAP | META_EDGE_RESISTANCE_WINDOWS);
|
||||||
|
|
||||||
update_resize (window, flags, x, y, FALSE);
|
queue_update_resize (window, flags, x, y);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -1235,8 +1235,7 @@ sync_request_timeout (gpointer data)
|
|||||||
meta_window_update_resize (window,
|
meta_window_update_resize (window,
|
||||||
window->display->grab_last_edge_resistance_flags,
|
window->display->grab_last_edge_resistance_flags,
|
||||||
window->display->grab_latest_motion_x,
|
window->display->grab_latest_motion_x,
|
||||||
window->display->grab_latest_motion_y,
|
window->display->grab_latest_motion_y);
|
||||||
TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -4160,8 +4159,7 @@ meta_window_x11_update_sync_request_counter (MetaWindow *window,
|
|||||||
meta_window_update_resize (window,
|
meta_window_update_resize (window,
|
||||||
window->display->grab_last_edge_resistance_flags,
|
window->display->grab_last_edge_resistance_flags,
|
||||||
window->display->grab_latest_motion_x,
|
window->display->grab_latest_motion_x,
|
||||||
window->display->grab_latest_motion_y,
|
window->display->grab_latest_motion_y);
|
||||||
TRUE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user