2009-06-25 22:56:15 +00:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
2023-07-21 13:37:20 +00:00
|
|
|
#pragma once
|
2009-06-25 22:56:15 +00:00
|
|
|
|
2009-06-26 19:33:20 +00:00
|
|
|
#include <X11/extensions/Xfixes.h>
|
|
|
|
|
compositor: Make sure _NET_WM_FRAME_DRAWN timestamp has the right scope
The timestamp sent with _NET_WM_FRAME_DRAWN should be in "high
resolution X server timestamps", meaning they should have the same scope
as the built in X11 32 bit unsigned integer timestamps, i.e. overflow at
the same time.
This was not done correctly when mutter had determined the X server used
the monotonic clock, where it'd just forward the monotonic clock,
confusing any client using _NET_WM_FRAME_DRAWN and friends.
Fix this by 1) splitting the timestamp conversiot into an X11 case and a
display server case, where the display server case simply clamps the
monotonic clock, as it is assumed Xwayland is always usign the monotonic
clock, and 2) if we're a X11 compositing manager, if the X server is
using the monotonic clock, apply the same semantics as the display
server case and always just clamp, or if not, calculate the offset every
10 seconds, and offset the monotonic clock timestamp with the calculated
X server timestamp offset.
This fixes an issue that would occur if mutter (or rather GNOME Shell)
would have been started before a X11 timestamp overflow, after the
overflow happened. In this case, GTK3 clients would get unclamped
timestamps, and get very confused, resulting in frames queued several
weeks into the future.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1494
2020-07-08 14:53:14 +00:00
|
|
|
#include "clutter/clutter-mutter.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "clutter/clutter.h"
|
compositor: Expose the MetaCompositorView in before_paint () vfunc
The idea is that the state of the MetaCompositorView shall be
up-to-date only in specific scenarios, thus allowing operations
performed on it to be queued and aggregated to be handled in the
right time, and only if they are still necessary.
For example, in a following commit, the top window actor in each
view will be planned (if needed) only once before painting a frame,
rendering the top window actor in the MetaCompositorView potentially
stale in all other times.
Similarly, if a MetaCompositorView is destroyed before the beginning
of the frame, a queued operation to update its top window actor can be
discarded.
As an interface segragation measure, and as part of an attempt to
avoid the use of g_return_if_fail () to check the validity of the
MetaCompositorView's state in multiple places (which is still prone to
human error), the interfaces through which a MetaCompositorView is
made available would only ones where it's state is gurenteed to be
up-to-date.
Specifically, this commit gurentees that the state of the
MetaCompositorView would be up-to-date during the before_paint () and
after_paint () vfuncs exposed to child classes of the MetaCompositor.
The frame_in_progress variable will be used in a following commit to
guarantee that the MetaCompositorView's state is not invalidated during
this time.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2526>
2022-07-11 09:23:24 +00:00
|
|
|
#include "compositor/meta-compositor-view.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "compositor/meta-plugin-manager.h"
|
|
|
|
#include "compositor/meta-window-actor-private.h"
|
2022-10-21 09:21:13 +00:00
|
|
|
#include "compositor/meta-window-drag.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "meta/compositor.h"
|
|
|
|
#include "meta/display.h"
|
2009-06-25 22:56:15 +00:00
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
/* Wait 2ms after vblank before starting to draw next frame */
|
|
|
|
#define META_SYNC_DELAY 2
|
2014-05-12 13:11:53 +00:00
|
|
|
|
2020-03-03 08:32:33 +00:00
|
|
|
typedef struct _MetaLaters MetaLaters;
|
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
struct _MetaCompositorClass
|
|
|
|
{
|
|
|
|
GObjectClass parent_class;
|
2019-08-14 21:25:54 +00:00
|
|
|
|
2020-03-03 08:27:33 +00:00
|
|
|
gboolean (* manage) (MetaCompositor *compositor,
|
|
|
|
GError **error);
|
2019-08-14 21:25:54 +00:00
|
|
|
void (* unmanage) (MetaCompositor *compositor);
|
compositor: Expose the MetaCompositorView in before_paint () vfunc
The idea is that the state of the MetaCompositorView shall be
up-to-date only in specific scenarios, thus allowing operations
performed on it to be queued and aggregated to be handled in the
right time, and only if they are still necessary.
For example, in a following commit, the top window actor in each
view will be planned (if needed) only once before painting a frame,
rendering the top window actor in the MetaCompositorView potentially
stale in all other times.
Similarly, if a MetaCompositorView is destroyed before the beginning
of the frame, a queued operation to update its top window actor can be
discarded.
As an interface segragation measure, and as part of an attempt to
avoid the use of g_return_if_fail () to check the validity of the
MetaCompositorView's state in multiple places (which is still prone to
human error), the interfaces through which a MetaCompositorView is
made available would only ones where it's state is gurenteed to be
up-to-date.
Specifically, this commit gurentees that the state of the
MetaCompositorView would be up-to-date during the before_paint () and
after_paint () vfuncs exposed to child classes of the MetaCompositor.
The frame_in_progress variable will be used in a following commit to
guarantee that the MetaCompositorView's state is not invalidated during
this time.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2526>
2022-07-11 09:23:24 +00:00
|
|
|
void (* before_paint) (MetaCompositor *compositor,
|
|
|
|
MetaCompositorView *compositor_view);
|
|
|
|
void (* after_paint) (MetaCompositor *compositor,
|
|
|
|
MetaCompositorView *compositor_view);
|
2019-08-14 21:25:54 +00:00
|
|
|
void (* remove_window) (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
compositor: Make sure _NET_WM_FRAME_DRAWN timestamp has the right scope
The timestamp sent with _NET_WM_FRAME_DRAWN should be in "high
resolution X server timestamps", meaning they should have the same scope
as the built in X11 32 bit unsigned integer timestamps, i.e. overflow at
the same time.
This was not done correctly when mutter had determined the X server used
the monotonic clock, where it'd just forward the monotonic clock,
confusing any client using _NET_WM_FRAME_DRAWN and friends.
Fix this by 1) splitting the timestamp conversiot into an X11 case and a
display server case, where the display server case simply clamps the
monotonic clock, as it is assumed Xwayland is always usign the monotonic
clock, and 2) if we're a X11 compositing manager, if the X server is
using the monotonic clock, apply the same semantics as the display
server case and always just clamp, or if not, calculate the offset every
10 seconds, and offset the monotonic clock timestamp with the calculated
X server timestamp offset.
This fixes an issue that would occur if mutter (or rather GNOME Shell)
would have been started before a X11 timestamp overflow, after the
overflow happened. In this case, GTK3 clients would get unclamped
timestamps, and get very confused, resulting in frames queued several
weeks into the future.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1494
2020-07-08 14:53:14 +00:00
|
|
|
int64_t (* monotonic_to_high_res_xserver_time) (MetaCompositor *compositor,
|
|
|
|
int64_t time_us);
|
2021-02-13 11:48:31 +00:00
|
|
|
void (* grab_begin) (MetaCompositor *compositor);
|
|
|
|
void (* grab_end) (MetaCompositor *compositor);
|
2022-07-15 09:06:12 +00:00
|
|
|
|
|
|
|
MetaCompositorView * (* create_view) (MetaCompositor *compositor,
|
|
|
|
ClutterStageView *stage_view);
|
2009-06-26 19:33:20 +00:00
|
|
|
};
|
|
|
|
|
2020-03-03 08:27:33 +00:00
|
|
|
gboolean meta_compositor_do_manage (MetaCompositor *compositor,
|
|
|
|
GError **error);
|
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
|
|
|
|
MetaWindowActor *window_actor);
|
2012-11-12 19:11:08 +00:00
|
|
|
|
2022-07-02 19:51:13 +00:00
|
|
|
void meta_compositor_window_actor_stage_views_changed (MetaCompositor *compositor);
|
|
|
|
|
2014-03-18 21:31:22 +00:00
|
|
|
void meta_switch_workspace_completed (MetaCompositor *compositor);
|
2010-10-18 17:27:14 +00:00
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor);
|
|
|
|
|
compositor: Make sure _NET_WM_FRAME_DRAWN timestamp has the right scope
The timestamp sent with _NET_WM_FRAME_DRAWN should be in "high
resolution X server timestamps", meaning they should have the same scope
as the built in X11 32 bit unsigned integer timestamps, i.e. overflow at
the same time.
This was not done correctly when mutter had determined the X server used
the monotonic clock, where it'd just forward the monotonic clock,
confusing any client using _NET_WM_FRAME_DRAWN and friends.
Fix this by 1) splitting the timestamp conversiot into an X11 case and a
display server case, where the display server case simply clamps the
monotonic clock, as it is assumed Xwayland is always usign the monotonic
clock, and 2) if we're a X11 compositing manager, if the X server is
using the monotonic clock, apply the same semantics as the display
server case and always just clamp, or if not, calculate the offset every
10 seconds, and offset the monotonic clock timestamp with the calculated
X server timestamp offset.
This fixes an issue that would occur if mutter (or rather GNOME Shell)
would have been started before a X11 timestamp overflow, after the
overflow happened. In this case, GTK3 clients would get unclamped
timestamps, and get very confused, resulting in frames queued several
weeks into the future.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1494
2020-07-08 14:53:14 +00:00
|
|
|
int64_t meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
|
|
|
|
int64_t monotonic_time_us);
|
2012-11-12 19:09:38 +00:00
|
|
|
|
2016-03-08 04:10:21 +00:00
|
|
|
void meta_compositor_flash_window (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
2017-01-26 18:48:52 +00:00
|
|
|
MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
2017-06-14 09:20:54 +00:00
|
|
|
MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
2019-02-20 10:07:22 +00:00
|
|
|
void meta_compositor_locate_pointer (MetaCompositor *compositor);
|
|
|
|
|
2019-08-14 21:25:54 +00:00
|
|
|
gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor);
|
|
|
|
|
2019-08-14 17:04:41 +00:00
|
|
|
MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor);
|
|
|
|
|
2022-02-05 12:12:48 +00:00
|
|
|
MetaBackend * meta_compositor_get_backend (MetaCompositor *compositor);
|
|
|
|
|
2019-08-14 21:25:54 +00:00
|
|
|
MetaWindowActor * meta_compositor_get_top_window_actor (MetaCompositor *compositor);
|
2019-08-14 17:04:41 +00:00
|
|
|
|
|
|
|
ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
|
|
|
|
|
|
|
|
gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
|
|
|
|
|
2022-10-21 17:52:35 +00:00
|
|
|
gboolean meta_compositor_drag_window (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaGrabOp grab_op,
|
|
|
|
ClutterInputDevice *device,
|
|
|
|
ClutterEventSequence *sequence,
|
|
|
|
uint32_t timestamp);
|
2022-10-21 09:21:13 +00:00
|
|
|
|
|
|
|
MetaWindowDrag * meta_compositor_get_current_window_drag (MetaCompositor *compositor);
|
|
|
|
|
2021-11-17 22:31:11 +00:00
|
|
|
void meta_compositor_grab_begin (MetaCompositor *compositor);
|
2022-09-07 15:45:23 +00:00
|
|
|
|
2021-11-17 22:31:11 +00:00
|
|
|
void meta_compositor_grab_end (MetaCompositor *compositor);
|
|
|
|
|
2022-09-07 15:45:23 +00:00
|
|
|
void meta_compositor_destroy (MetaCompositor *compositor);
|
|
|
|
|
|
|
|
void meta_compositor_manage (MetaCompositor *compositor);
|
|
|
|
|
|
|
|
void meta_compositor_unmanage (MetaCompositor *compositor);
|
|
|
|
|
|
|
|
void meta_compositor_window_shape_changed (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
|
|
|
void meta_compositor_window_opacity_changed (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
|
|
|
gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
|
|
|
|
void meta_compositor_add_window (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
|
|
|
void meta_compositor_remove_window (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
|
|
|
void meta_compositor_show_window (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaCompEffect effect);
|
|
|
|
|
|
|
|
void meta_compositor_hide_window (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaCompEffect effect);
|
|
|
|
|
|
|
|
void meta_compositor_switch_workspace (MetaCompositor *compositor,
|
|
|
|
MetaWorkspace *from,
|
|
|
|
MetaWorkspace *to,
|
|
|
|
MetaMotionDirection direction);
|
|
|
|
|
|
|
|
void meta_compositor_size_change_window (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaSizeChange which_change,
|
|
|
|
MetaRectangle *old_frame_rect,
|
|
|
|
MetaRectangle *old_buffer_rect);
|
|
|
|
|
|
|
|
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
gboolean did_placement);
|
|
|
|
|
|
|
|
void meta_compositor_sync_updates_frozen (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window);
|
|
|
|
|
|
|
|
void meta_compositor_queue_frame_drawn (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
gboolean no_delay_frame);
|
|
|
|
|
|
|
|
void meta_compositor_sync_stack (MetaCompositor *compositor,
|
|
|
|
GList *stack);
|
|
|
|
|
|
|
|
void meta_compositor_flash_display (MetaCompositor *compositor,
|
|
|
|
MetaDisplay *display);
|
|
|
|
|
|
|
|
void meta_compositor_show_tile_preview (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaRectangle *tile_rect,
|
|
|
|
int tile_monitor_number);
|
|
|
|
|
|
|
|
void meta_compositor_hide_tile_preview (MetaCompositor *compositor);
|
|
|
|
|
|
|
|
void meta_compositor_show_window_menu (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaWindowMenuType menu,
|
|
|
|
int x,
|
|
|
|
int y);
|
|
|
|
|
|
|
|
void meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor,
|
|
|
|
MetaWindow *window,
|
|
|
|
MetaWindowMenuType menu,
|
|
|
|
MetaRectangle *rect);
|
|
|
|
|
compositor: Make sure _NET_WM_FRAME_DRAWN timestamp has the right scope
The timestamp sent with _NET_WM_FRAME_DRAWN should be in "high
resolution X server timestamps", meaning they should have the same scope
as the built in X11 32 bit unsigned integer timestamps, i.e. overflow at
the same time.
This was not done correctly when mutter had determined the X server used
the monotonic clock, where it'd just forward the monotonic clock,
confusing any client using _NET_WM_FRAME_DRAWN and friends.
Fix this by 1) splitting the timestamp conversiot into an X11 case and a
display server case, where the display server case simply clamps the
monotonic clock, as it is assumed Xwayland is always usign the monotonic
clock, and 2) if we're a X11 compositing manager, if the X server is
using the monotonic clock, apply the same semantics as the display
server case and always just clamp, or if not, calculate the offset every
10 seconds, and offset the monotonic clock timestamp with the calculated
X server timestamp offset.
This fixes an issue that would occur if mutter (or rather GNOME Shell)
would have been started before a X11 timestamp overflow, after the
overflow happened. In this case, GTK3 clients would get unclamped
timestamps, and get very confused, resulting in frames queued several
weeks into the future.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1494
2020-07-08 14:53:14 +00:00
|
|
|
/*
|
|
|
|
* This function takes a 64 bit time stamp from the monotonic clock, and clamps
|
|
|
|
* it to the scope of the X server clock, without losing the granularity.
|
|
|
|
*/
|
|
|
|
static inline int64_t
|
|
|
|
meta_translate_to_high_res_xserver_time (int64_t time_us)
|
|
|
|
{
|
|
|
|
int64_t us;
|
|
|
|
int64_t ms;
|
|
|
|
|
|
|
|
us = time_us % 1000;
|
|
|
|
ms = time_us / 1000;
|
|
|
|
|
|
|
|
return ms2us (ms & 0xffffffff) + us;
|
|
|
|
}
|