mutter/src/compositor/compositor-private.h
Jonas Ådahl bf6dde87f8 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-10-12 14:48:21 +00:00

100 lines
3.7 KiB
C

/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef META_COMPOSITOR_PRIVATE_H
#define META_COMPOSITOR_PRIVATE_H
#include <X11/extensions/Xfixes.h>
#include "clutter/clutter-mutter.h"
#include "clutter/clutter.h"
#include "compositor/meta-plugin-manager.h"
#include "compositor/meta-window-actor-private.h"
#include "meta/compositor.h"
#include "meta/display.h"
/* Wait 2ms after vblank before starting to draw next frame */
#define META_SYNC_DELAY 2
typedef struct _MetaLaters MetaLaters;
struct _MetaCompositorClass
{
GObjectClass parent_class;
gboolean (* manage) (MetaCompositor *compositor,
GError **error);
void (* unmanage) (MetaCompositor *compositor);
void (* before_paint) (MetaCompositor *compositor,
ClutterStageView *stage_view);
void (* after_paint) (MetaCompositor *compositor,
ClutterStageView *stage_view);
void (* remove_window) (MetaCompositor *compositor,
MetaWindow *window);
int64_t (* monotonic_to_high_res_xserver_time) (MetaCompositor *compositor,
int64_t time_us);
};
gboolean meta_compositor_do_manage (MetaCompositor *compositor,
GError **error);
void meta_compositor_remove_window_actor (MetaCompositor *compositor,
MetaWindowActor *window_actor);
void meta_switch_workspace_completed (MetaCompositor *compositor);
gboolean meta_begin_modal_for_plugin (MetaCompositor *compositor,
MetaPlugin *plugin,
MetaModalOptions options,
guint32 timestamp);
void meta_end_modal_for_plugin (MetaCompositor *compositor,
MetaPlugin *plugin,
guint32 timestamp);
MetaPluginManager * meta_compositor_get_plugin_manager (MetaCompositor *compositor);
int64_t meta_compositor_monotonic_to_high_res_xserver_time (MetaCompositor *compositor,
int64_t monotonic_time_us);
void meta_compositor_flash_window (MetaCompositor *compositor,
MetaWindow *window);
MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *compositor,
MetaWindow *window);
MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
MetaWindow *window);
void meta_compositor_locate_pointer (MetaCompositor *compositor);
void meta_compositor_redirect_x11_windows (MetaCompositor *compositor);
gboolean meta_compositor_is_unredirect_inhibited (MetaCompositor *compositor);
MetaDisplay * meta_compositor_get_display (MetaCompositor *compositor);
MetaWindowActor * meta_compositor_get_top_window_actor (MetaCompositor *compositor);
ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor);
/*
* 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;
}
#endif /* META_COMPOSITOR_PRIVATE_H */