mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
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;
|
||||
|
||||
void (* post_init) (MetaBackend *backend);
|
||||
|
||||
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
|
||||
int device_id);
|
||||
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend);
|
||||
|
@ -77,6 +77,12 @@ meta_backend_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_post_init (MetaBackend *backend)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_class_init (MetaBackendClass *klass)
|
||||
{
|
||||
@ -84,6 +90,8 @@ meta_backend_class_init (MetaBackendClass *klass)
|
||||
|
||||
object_class->constructed = meta_backend_constructed;
|
||||
object_class->finalize = meta_backend_finalize;
|
||||
|
||||
klass->post_init = meta_backend_real_post_init;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_post_init (MetaBackend *backend)
|
||||
{
|
||||
META_BACKEND_GET_CLASS (backend)->post_init (backend);
|
||||
}
|
||||
|
||||
MetaIdleMonitor *
|
||||
meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
@ -217,4 +231,6 @@ meta_clutter_init (void)
|
||||
source = g_source_new (&event_funcs, sizeof (GSource));
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
meta_backend_post_init (_backend);
|
||||
}
|
||||
|
@ -26,15 +26,149 @@
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
#include <meta/util.h>
|
||||
#include "meta-idle-monitor-xsync.h"
|
||||
#include "meta-monitor-manager-xrandr.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 *
|
||||
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);
|
||||
|
||||
backend_class->post_init = meta_backend_x11_post_init;
|
||||
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
|
||||
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;
|
||||
}
|
||||
@ -69,35 +204,6 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
static void
|
||||
meta_backend_x11_init (MetaBackendX11 *x11)
|
||||
{
|
||||
/* When running as an X11 compositor, we install our own event filter and
|
||||
* pass events to Clutter explicitly, so we need to prevent Clutter from
|
||||
* 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 ()));
|
||||
/* We do X11 event retrieval ourselves */
|
||||
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 "workspace-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/native/meta-idle-monitor-native.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);
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user