wayland: Add xdg-output support
The xdg-output protocol aims at describing outputs in way which is more in line with the concept of an output on desktop oriented systems. For now it just features the position and logical size which describe the output position and size in the global compositor space. This is however much useful for Xwayland to advertise the output size and position to X11 clients which need this to configure their surfaces in the global compositor space as the compositor may apply a different scale from what is advertised by the output scaling property (to achieve fractional scaling, for example). This was added in wayland-protocols 1.10. https://bugzilla.gnome.org/show_bug.cgi?id=787363
This commit is contained in:
parent
b505eb261e
commit
db32047a5d
6 changed files with 204 additions and 7 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -88,6 +88,8 @@ src/pointer-constraints-unstable-v*-protocol.c
|
|||
src/pointer-constraints-unstable-v*-server-protocol.h
|
||||
src/xdg-foreign-unstable-v*-protocol.c
|
||||
src/xdg-foreign-unstable-v*-server-protocol.h
|
||||
src/xdg-output-unstable-v1-protocol.c
|
||||
src/xdg-output-unstable-v1-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
src/libmutter-*.pc
|
||||
doc/reference/*.args
|
||||
|
|
|
@ -306,7 +306,7 @@ AS_IF([test "$have_wayland" = "yes"], [
|
|||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
|
||||
PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.9],
|
||||
PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.10],
|
||||
[ac_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`])
|
||||
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
|
||||
])
|
||||
|
|
|
@ -82,6 +82,8 @@ mutter_built_sources += \
|
|||
linux-dmabuf-unstable-v1-server-protocol.h \
|
||||
keyboard-shortcuts-inhibit-unstable-v1-protocol.c \
|
||||
keyboard-shortcuts-inhibit-unstable-v1-server-protocol.h \
|
||||
xdg-output-unstable-v1-protocol.c \
|
||||
xdg-output-unstable-v1-server-protocol.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
@ -742,3 +744,7 @@ keyboard-shortcuts-inhibit-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)
|
|||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
keyboard-shortcuts-inhibit-unstable-v1-server-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@
|
||||
xdg-output-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
xdg-output-unstable-v1-server-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/xdg-output/xdg-output-unstable-v1.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "meta-wayland-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
#include "xdg-output-unstable-v1-server-protocol.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -42,6 +43,13 @@ static guint signals[LAST_SIGNAL];
|
|||
|
||||
G_DEFINE_TYPE (MetaWaylandOutput, meta_wayland_output, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
send_xdg_output_events (struct wl_resource *resource,
|
||||
MetaWaylandOutput *wayland_output,
|
||||
MetaLogicalMonitor *logical_monitor,
|
||||
gboolean need_all_events,
|
||||
gboolean *pending_done_event);
|
||||
|
||||
static void
|
||||
output_resource_destroy (struct wl_resource *res)
|
||||
{
|
||||
|
@ -124,7 +132,8 @@ static void
|
|||
send_output_events (struct wl_resource *resource,
|
||||
MetaWaylandOutput *wayland_output,
|
||||
MetaLogicalMonitor *logical_monitor,
|
||||
gboolean need_all_events)
|
||||
gboolean need_all_events,
|
||||
gboolean *pending_done_event)
|
||||
{
|
||||
int version = wl_resource_get_version (resource);
|
||||
MetaMonitor *monitor;
|
||||
|
@ -221,10 +230,16 @@ send_output_events (struct wl_resource *resource,
|
|||
wl_output_send_scale (resource, scale);
|
||||
need_done = TRUE;
|
||||
}
|
||||
|
||||
if (need_done)
|
||||
wl_output_send_done (resource);
|
||||
}
|
||||
|
||||
if (need_all_events && version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
||||
{
|
||||
wl_output_send_done (resource);
|
||||
need_done = FALSE;
|
||||
}
|
||||
|
||||
if (pending_done_event && need_done)
|
||||
*pending_done_event = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -253,7 +268,7 @@ bind_output (struct wl_client *client,
|
|||
logical_monitor->rect.width, logical_monitor->rect.height,
|
||||
wayland_output->refresh_rate);
|
||||
|
||||
send_output_events (resource, wayland_output, logical_monitor, TRUE);
|
||||
send_output_events (resource, wayland_output, logical_monitor, TRUE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -291,13 +306,37 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
|
|||
MetaLogicalMonitor *logical_monitor)
|
||||
{
|
||||
GList *iter;
|
||||
gboolean pending_done_event;
|
||||
|
||||
pending_done_event = FALSE;
|
||||
for (iter = wayland_output->resources; iter; iter = iter->next)
|
||||
{
|
||||
struct wl_resource *resource = iter->data;
|
||||
send_output_events (resource, wayland_output, logical_monitor, FALSE);
|
||||
send_output_events (resource, wayland_output, logical_monitor, FALSE, &pending_done_event);
|
||||
}
|
||||
|
||||
for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next)
|
||||
{
|
||||
struct wl_resource *xdg_output = iter->data;
|
||||
send_xdg_output_events (xdg_output, wayland_output, logical_monitor, FALSE, &pending_done_event);
|
||||
}
|
||||
|
||||
/* Send the "done" events if needed */
|
||||
if (pending_done_event)
|
||||
{
|
||||
for (iter = wayland_output->resources; iter; iter = iter->next)
|
||||
{
|
||||
struct wl_resource *resource = iter->data;
|
||||
if (wl_resource_get_version (resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
|
||||
wl_output_send_done (resource);
|
||||
}
|
||||
|
||||
for (iter = wayland_output->xdg_output_resources; iter; iter = iter->next)
|
||||
{
|
||||
struct wl_resource *xdg_output = iter->data;
|
||||
zxdg_output_v1_send_done (xdg_output);
|
||||
}
|
||||
}
|
||||
/* It's very important that we change the output pointer here, as
|
||||
the old structure is about to be freed by MetaMonitorManager */
|
||||
meta_wayland_output_set_logical_monitor (wayland_output, logical_monitor);
|
||||
|
@ -398,6 +437,15 @@ meta_wayland_output_finalize (GObject *object)
|
|||
|
||||
g_list_free (wayland_output->resources);
|
||||
|
||||
for (l = wayland_output->xdg_output_resources; l; l = l->next)
|
||||
{
|
||||
struct wl_resource *xdg_output_resource = l->data;
|
||||
|
||||
wl_resource_set_user_data (xdg_output_resource, NULL);
|
||||
}
|
||||
|
||||
g_list_free (wayland_output->xdg_output_resources);
|
||||
|
||||
G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -416,6 +464,139 @@ meta_wayland_output_class_init (MetaWaylandOutputClass *klass)
|
|||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_xdg_output_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandOutput *wayland_output;
|
||||
|
||||
wayland_output = wl_resource_get_user_data (resource);
|
||||
if (!wayland_output)
|
||||
return;
|
||||
|
||||
wayland_output->xdg_output_resources =
|
||||
g_list_remove (wayland_output->xdg_output_resources, resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_xdg_output_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_interface
|
||||
meta_xdg_output_interface = {
|
||||
meta_xdg_output_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
send_xdg_output_events (struct wl_resource *resource,
|
||||
MetaWaylandOutput *wayland_output,
|
||||
MetaLogicalMonitor *logical_monitor,
|
||||
gboolean need_all_events,
|
||||
gboolean *pending_done_event)
|
||||
{
|
||||
MetaRectangle new_layout;
|
||||
MetaRectangle old_layout;
|
||||
MetaLogicalMonitor *old_logical_monitor;
|
||||
gboolean need_done;
|
||||
|
||||
need_done = FALSE;
|
||||
old_logical_monitor = wayland_output->logical_monitor;
|
||||
old_layout = meta_logical_monitor_get_layout (old_logical_monitor);
|
||||
new_layout = meta_logical_monitor_get_layout (logical_monitor);
|
||||
|
||||
if (need_all_events ||
|
||||
old_layout.x != new_layout.x ||
|
||||
old_layout.y != new_layout.y)
|
||||
{
|
||||
zxdg_output_v1_send_logical_position (resource,
|
||||
new_layout.x,
|
||||
new_layout.y);
|
||||
need_done = TRUE;
|
||||
}
|
||||
|
||||
if (need_all_events ||
|
||||
old_layout.width != new_layout.width ||
|
||||
old_layout.height != new_layout.height)
|
||||
{
|
||||
zxdg_output_v1_send_logical_position (resource,
|
||||
new_layout.width,
|
||||
new_layout.height);
|
||||
need_done = TRUE;
|
||||
}
|
||||
|
||||
if (need_all_events)
|
||||
{
|
||||
zxdg_output_v1_send_done (resource);
|
||||
need_done = FALSE;
|
||||
}
|
||||
|
||||
if (pending_done_event && need_done)
|
||||
*pending_done_event = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_xdg_output_manager_get_xdg_output (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *output)
|
||||
{
|
||||
struct wl_resource *xdg_output_resource;
|
||||
MetaWaylandOutput *wayland_output;
|
||||
|
||||
xdg_output_resource = wl_resource_create (client,
|
||||
&zxdg_output_v1_interface,
|
||||
wl_resource_get_version (resource),
|
||||
id);
|
||||
|
||||
wl_resource_set_implementation (xdg_output_resource,
|
||||
&meta_xdg_output_interface,
|
||||
NULL, meta_xdg_output_destructor);
|
||||
|
||||
wayland_output = wl_resource_get_user_data (output);
|
||||
if (!wayland_output)
|
||||
return;
|
||||
|
||||
wayland_output->xdg_output_resources =
|
||||
g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);
|
||||
|
||||
send_xdg_output_events (xdg_output_resource,
|
||||
wayland_output,
|
||||
wayland_output->logical_monitor,
|
||||
TRUE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_xdg_output_manager_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct zxdg_output_manager_v1_interface
|
||||
meta_xdg_output_manager_interface = {
|
||||
meta_xdg_output_manager_destroy,
|
||||
meta_xdg_output_manager_get_xdg_output,
|
||||
};
|
||||
|
||||
static void
|
||||
bind_xdg_output_manager (struct wl_client *client,
|
||||
void *data,
|
||||
uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client,
|
||||
&zxdg_output_manager_v1_interface,
|
||||
version, id);
|
||||
|
||||
wl_resource_set_implementation (resource,
|
||||
&meta_xdg_output_manager_interface,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_outputs_init (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
|
@ -427,4 +608,10 @@ meta_wayland_outputs_init (MetaWaylandCompositor *compositor)
|
|||
|
||||
compositor->outputs = g_hash_table_new_full (NULL, NULL, NULL, wayland_output_destroy_notify);
|
||||
compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors);
|
||||
|
||||
wl_global_create (compositor->wayland_display,
|
||||
&zxdg_output_manager_v1_interface,
|
||||
META_ZXDG_OUTPUT_V1_VERSION,
|
||||
NULL,
|
||||
bind_xdg_output_manager);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ struct _MetaWaylandOutput
|
|||
gint scale;
|
||||
|
||||
GList *resources;
|
||||
GList *xdg_output_resources;
|
||||
};
|
||||
|
||||
void meta_wayland_outputs_init (MetaWaylandCompositor *compositor);
|
||||
|
|
|
@ -49,5 +49,6 @@
|
|||
#define META_ZXDG_IMPORTER_V1_VERSION 1
|
||||
#define META_ZWP_LINUX_DMABUF_V1_VERSION 3
|
||||
#define META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION 1
|
||||
#define META_ZXDG_OUTPUT_V1_VERSION 1
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue