backend: Poll events from the host X11 server ourselves
I was accidentally pulling events from the Xwayland server under nested for the idle monitor, which is wrong. Whoops.
This commit is contained in:
parent
3c0ca1f2af
commit
3d091e514d
@ -49,6 +49,8 @@ struct _MetaBackendClass
|
|||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
void (* post_init) (MetaBackend *backend);
|
||||||
|
|
||||||
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
|
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
|
||||||
int device_id);
|
int device_id);
|
||||||
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend);
|
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend);
|
||||||
|
@ -77,6 +77,12 @@ meta_backend_finalize (GObject *object)
|
|||||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_backend_real_post_init (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_backend_class_init (MetaBackendClass *klass)
|
meta_backend_class_init (MetaBackendClass *klass)
|
||||||
{
|
{
|
||||||
@ -84,6 +90,8 @@ meta_backend_class_init (MetaBackendClass *klass)
|
|||||||
|
|
||||||
object_class->constructed = meta_backend_constructed;
|
object_class->constructed = meta_backend_constructed;
|
||||||
object_class->finalize = meta_backend_finalize;
|
object_class->finalize = meta_backend_finalize;
|
||||||
|
|
||||||
|
klass->post_init = meta_backend_real_post_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -109,6 +117,12 @@ meta_backend_create_idle_monitor (MetaBackend *backend,
|
|||||||
return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id);
|
return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_backend_post_init (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
META_BACKEND_GET_CLASS (backend)->post_init (backend);
|
||||||
|
}
|
||||||
|
|
||||||
MetaIdleMonitor *
|
MetaIdleMonitor *
|
||||||
meta_backend_get_idle_monitor (MetaBackend *backend,
|
meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||||
int device_id)
|
int device_id)
|
||||||
@ -217,4 +231,6 @@ meta_clutter_init (void)
|
|||||||
source = g_source_new (&event_funcs, sizeof (GSource));
|
source = g_source_new (&event_funcs, sizeof (GSource));
|
||||||
g_source_attach (source, NULL);
|
g_source_attach (source, NULL);
|
||||||
g_source_unref (source);
|
g_source_unref (source);
|
||||||
|
|
||||||
|
meta_backend_post_init (_backend);
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,149 @@
|
|||||||
|
|
||||||
#include "meta-backend-x11.h"
|
#include "meta-backend-x11.h"
|
||||||
|
|
||||||
#include <gdk/gdkx.h>
|
|
||||||
#include <clutter/x11/clutter-x11.h>
|
#include <clutter/x11/clutter-x11.h>
|
||||||
|
|
||||||
|
#include <X11/extensions/sync.h>
|
||||||
|
|
||||||
#include <meta/util.h>
|
#include <meta/util.h>
|
||||||
#include "meta-idle-monitor-xsync.h"
|
#include "meta-idle-monitor-xsync.h"
|
||||||
#include "meta-monitor-manager-xrandr.h"
|
#include "meta-monitor-manager-xrandr.h"
|
||||||
#include "backends/meta-monitor-manager-dummy.h"
|
#include "backends/meta-monitor-manager-dummy.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND);
|
struct _MetaBackendX11Private
|
||||||
|
{
|
||||||
|
/* The host X11 display */
|
||||||
|
Display *xdisplay;
|
||||||
|
GSource *source;
|
||||||
|
|
||||||
|
int xsync_event_base;
|
||||||
|
int xsync_error_base;
|
||||||
|
};
|
||||||
|
typedef struct _MetaBackendX11Private MetaBackendX11Private;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND);
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_alarm_notify (MetaBackend *backend,
|
||||||
|
XEvent *xevent)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i <= backend->device_id_max; i++)
|
||||||
|
if (backend->device_monitors[i])
|
||||||
|
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*)xevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_host_xevent (MetaBackend *backend,
|
||||||
|
XEvent *xevent)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
|
||||||
|
if (xevent->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
||||||
|
handle_alarm_notify (backend, xevent);
|
||||||
|
|
||||||
|
clutter_x11_handle_event (xevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GSource base;
|
||||||
|
GPollFD event_poll_fd;
|
||||||
|
MetaBackend *backend;
|
||||||
|
} XEventSource;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
x_event_source_prepare (GSource *source,
|
||||||
|
int *timeout)
|
||||||
|
{
|
||||||
|
XEventSource *x_source = (XEventSource *) source;
|
||||||
|
MetaBackend *backend = x_source->backend;
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
|
||||||
|
*timeout = -1;
|
||||||
|
|
||||||
|
return XPending (priv->xdisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
x_event_source_check (GSource *source)
|
||||||
|
{
|
||||||
|
XEventSource *x_source = (XEventSource *) source;
|
||||||
|
MetaBackend *backend = x_source->backend;
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
|
||||||
|
return XPending (priv->xdisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
x_event_source_dispatch (GSource *source,
|
||||||
|
GSourceFunc callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
XEventSource *x_source = (XEventSource *) source;
|
||||||
|
MetaBackend *backend = x_source->backend;
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
|
||||||
|
while (XPending (priv->xdisplay))
|
||||||
|
{
|
||||||
|
XEvent xev;
|
||||||
|
|
||||||
|
XNextEvent (priv->xdisplay, &xev);
|
||||||
|
|
||||||
|
handle_host_xevent (backend, &xev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSourceFuncs x_event_funcs = {
|
||||||
|
x_event_source_prepare,
|
||||||
|
x_event_source_check,
|
||||||
|
x_event_source_dispatch,
|
||||||
|
};
|
||||||
|
|
||||||
|
static GSource *
|
||||||
|
x_event_source_new (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
GSource *source;
|
||||||
|
XEventSource *x_source;
|
||||||
|
|
||||||
|
source = g_source_new (&x_event_funcs, sizeof (XEventSource));
|
||||||
|
x_source = (XEventSource *) source;
|
||||||
|
x_source->backend = backend;
|
||||||
|
x_source->event_poll_fd.fd = ConnectionNumber (priv->xdisplay);
|
||||||
|
x_source->event_poll_fd.events = G_IO_IN;
|
||||||
|
g_source_add_poll (source, &x_source->event_poll_fd);
|
||||||
|
|
||||||
|
g_source_attach (source, NULL);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_backend_x11_post_init (MetaBackend *backend)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
priv->xdisplay = clutter_x11_get_default_display ();
|
||||||
|
|
||||||
|
priv->source = x_event_source_new (backend);
|
||||||
|
|
||||||
|
if (!XSyncQueryExtension (priv->xdisplay, &priv->xsync_event_base, &priv->xsync_error_base))
|
||||||
|
meta_fatal ("Could not initialize XSync");
|
||||||
|
|
||||||
|
if (!XSyncInitialize (priv->xdisplay, &major, &minor))
|
||||||
|
meta_fatal ("Could not initialize XSync");
|
||||||
|
|
||||||
|
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
|
||||||
|
}
|
||||||
|
|
||||||
static MetaIdleMonitor *
|
static MetaIdleMonitor *
|
||||||
meta_backend_x11_create_idle_monitor (MetaBackend *backend,
|
meta_backend_x11_create_idle_monitor (MetaBackend *backend,
|
||||||
@ -62,6 +196,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
|||||||
{
|
{
|
||||||
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
|
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
|
||||||
|
|
||||||
|
backend_class->post_init = meta_backend_x11_post_init;
|
||||||
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
|
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
|
||||||
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;
|
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;
|
||||||
}
|
}
|
||||||
@ -69,35 +204,6 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
|||||||
static void
|
static void
|
||||||
meta_backend_x11_init (MetaBackendX11 *x11)
|
meta_backend_x11_init (MetaBackendX11 *x11)
|
||||||
{
|
{
|
||||||
/* When running as an X11 compositor, we install our own event filter and
|
/* We do X11 event retrieval ourselves */
|
||||||
* pass events to Clutter explicitly, so we need to prevent Clutter from
|
clutter_x11_disable_event_retrieval ();
|
||||||
* handling our events.
|
|
||||||
*
|
|
||||||
* However, when running as a Wayland compostior under X11 nested, Clutter
|
|
||||||
* Clutter needs to see events related to its own window. We need to
|
|
||||||
* eventually replace this with a proper frontend / backend split: Clutter
|
|
||||||
* under nested is connecting to the "host X server" to get its events it
|
|
||||||
* needs to put up a window, and GTK+ is connecting to the "inner X server".
|
|
||||||
* The two would the same in the X11 compositor case, but not when running
|
|
||||||
* XWayland as a Wayland compositor.
|
|
||||||
*/
|
|
||||||
if (!meta_is_wayland_compositor ())
|
|
||||||
{
|
|
||||||
clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
|
||||||
clutter_x11_disable_event_retrieval ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_backend_x11_handle_alarm_notify (MetaBackend *backend,
|
|
||||||
XEvent *xevent)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!META_IS_BACKEND_X11 (backend))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i <= backend->device_id_max; i++)
|
|
||||||
if (backend->device_monitors[i])
|
|
||||||
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*)xevent);
|
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include "bell.h"
|
#include "bell.h"
|
||||||
#include "workspace-private.h"
|
#include "workspace-private.h"
|
||||||
#include "backends/meta-backend.h"
|
#include "backends/meta-backend.h"
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
|
||||||
#include "backends/native/meta-idle-monitor-native.h"
|
#include "backends/native/meta-idle-monitor-native.h"
|
||||||
|
|
||||||
#include "x11/window-x11.h"
|
#include "x11/window-x11.h"
|
||||||
@ -1264,11 +1263,6 @@ handle_other_xevent (MetaDisplay *display,
|
|||||||
meta_window_update_sync_request_counter (alarm_window, new_counter_value);
|
meta_window_update_sync_request_counter (alarm_window, new_counter_value);
|
||||||
bypass_gtk = TRUE; /* GTK doesn't want to see this really */
|
bypass_gtk = TRUE; /* GTK doesn't want to see this really */
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
meta_backend_x11_handle_alarm_notify (backend, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user