Copy layersurface & layer shell protocol from phosh (https://gitlab.gnome.org/World/Phosh/phosh/)
831 lines
25 KiB
C
831 lines
25 KiB
C
/*
|
|
* Copyright (C) 2018-2023 Purism SPC
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* Author: Guido Günther <agx@sigxcpu.org>
|
|
*/
|
|
/*
|
|
|
|
WARNING: this file is taken directly from phosh, with no modificaions apart
|
|
from this message. Please update phosh instead of changing this file. Please
|
|
copy the file back here afterwards, with an updated version of this notice.
|
|
|
|
Up-to-date with Phosh revision 953894a2.
|
|
|
|
*/
|
|
|
|
#define G_LOG_DOMAIN "phosh-layer-surface"
|
|
|
|
#include "config.h"
|
|
#include "layersurface.h"
|
|
|
|
#include <gdk/gdkwayland.h>
|
|
|
|
/**
|
|
* PhoshLayerSurface:
|
|
*
|
|
* A #GtkWindow rendered as a LayerSurface by the compositor
|
|
*
|
|
* #PhoshLayerSurface allows to use a Wayland surface backed by the
|
|
* layer-shell protocol as #GtkWindow. This allows to render e.g. panels and
|
|
* backgrounds using GTK.
|
|
*/
|
|
|
|
enum {
|
|
PHOSH_LAYER_SURFACE_PROP_0,
|
|
PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL,
|
|
PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT,
|
|
PHOSH_LAYER_SURFACE_PROP_ANCHOR,
|
|
PHOSH_LAYER_SURFACE_PROP_LAYER,
|
|
PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY,
|
|
PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE,
|
|
PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP,
|
|
PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM,
|
|
PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT,
|
|
PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT,
|
|
PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH,
|
|
PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT,
|
|
PHOSH_LAYER_SURFACE_PROP_CONFIGURED_WIDTH,
|
|
PHOSH_LAYER_SURFACE_PROP_CONFIGURED_HEIGHT,
|
|
PHOSH_LAYER_SURFACE_PROP_NAMESPACE,
|
|
PHOSH_LAYER_SURFACE_PROP_LAST_PROP
|
|
};
|
|
static GParamSpec *props[PHOSH_LAYER_SURFACE_PROP_LAST_PROP];
|
|
|
|
enum {
|
|
CONFIGURED,
|
|
N_SIGNALS
|
|
};
|
|
static guint signals [N_SIGNALS];
|
|
|
|
typedef struct {
|
|
struct wl_surface *wl_surface;
|
|
struct zwlr_layer_surface_v1 *layer_surface;
|
|
|
|
/* Properties */
|
|
guint anchor;
|
|
guint layer;
|
|
gboolean kbd_interactivity;
|
|
int exclusive_zone;
|
|
int margin_top, margin_bottom;
|
|
int margin_left, margin_right;
|
|
int width, height;
|
|
int configured_width, configured_height;
|
|
char *namespace;
|
|
struct zwlr_layer_shell_v1 *layer_shell;
|
|
struct wl_output *wl_output;
|
|
} PhoshLayerSurfacePrivate;
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (PhoshLayerSurface, phosh_layer_surface, GTK_TYPE_WINDOW)
|
|
|
|
|
|
static void
|
|
layer_surface_configure (void *data,
|
|
struct zwlr_layer_surface_v1 *surface,
|
|
uint32_t serial,
|
|
uint32_t width,
|
|
uint32_t height)
|
|
{
|
|
PhoshLayerSurface *self = data;
|
|
PhoshLayerSurfacePrivate *priv;
|
|
gboolean changed = FALSE;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
gtk_window_resize (GTK_WINDOW (self), width, height);
|
|
zwlr_layer_surface_v1_ack_configure (surface, serial);
|
|
|
|
if (priv->configured_height != height) {
|
|
priv->configured_height = height;
|
|
changed = TRUE;
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_CONFIGURED_HEIGHT]);
|
|
}
|
|
|
|
if (priv->configured_width != width) {
|
|
priv->configured_width = width;
|
|
changed = TRUE;
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_CONFIGURED_WIDTH]);
|
|
}
|
|
|
|
g_debug ("Configured %s (%p) (%dx%d)", priv->namespace, self, width, height);
|
|
if (changed)
|
|
g_signal_emit (self, signals[CONFIGURED], 0);
|
|
}
|
|
|
|
|
|
static void
|
|
layer_surface_closed (void *data,
|
|
struct zwlr_layer_surface_v1 *surface)
|
|
{
|
|
PhoshLayerSurface *self = data;
|
|
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
g_return_if_fail (priv->layer_surface == surface);
|
|
g_debug ("Destroying layer surface '%s'", priv->namespace);
|
|
zwlr_layer_surface_v1_destroy (priv->layer_surface);
|
|
priv->layer_surface = NULL;
|
|
gtk_widget_destroy (GTK_WIDGET (self));
|
|
}
|
|
|
|
|
|
static struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
|
.configure = layer_surface_configure,
|
|
.closed = layer_surface_closed,
|
|
};
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
|
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
|
int width, height;
|
|
|
|
switch (property_id) {
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL:
|
|
priv->layer_shell = g_value_get_pointer (value);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT:
|
|
priv->wl_output = g_value_get_pointer (value);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_ANCHOR:
|
|
priv->anchor = g_value_get_uint (value);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER:
|
|
phosh_layer_surface_set_layer (self, g_value_get_uint (value));
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY:
|
|
phosh_layer_surface_set_kbd_interactivity (self, g_value_get_boolean (value));
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE:
|
|
phosh_layer_surface_set_exclusive_zone (self, g_value_get_int (value));
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP:
|
|
phosh_layer_surface_set_margins (self,
|
|
g_value_get_int (value),
|
|
priv->margin_right,
|
|
priv->margin_bottom,
|
|
priv->margin_left);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM:
|
|
phosh_layer_surface_set_margins (self,
|
|
priv->margin_top,
|
|
priv->margin_right,
|
|
g_value_get_int (value),
|
|
priv->margin_left);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT:
|
|
phosh_layer_surface_set_margins (self,
|
|
priv->margin_top,
|
|
priv->margin_right,
|
|
priv->margin_bottom,
|
|
g_value_get_int (value));
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT:
|
|
phosh_layer_surface_set_margins (self,
|
|
priv->margin_top,
|
|
g_value_get_int (value),
|
|
priv->margin_bottom,
|
|
priv->margin_left);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH:
|
|
width = g_value_get_uint (value);
|
|
phosh_layer_surface_set_size (self, width, priv->height);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT:
|
|
height = g_value_get_uint (value);
|
|
phosh_layer_surface_set_size (self, priv->width, height);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_NAMESPACE:
|
|
g_free (priv->namespace);
|
|
priv->namespace = g_value_dup_string (value);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
|
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
switch (property_id) {
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL:
|
|
g_value_set_pointer (value, priv->layer_shell);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT:
|
|
g_value_set_pointer (value, priv->wl_output);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_ANCHOR:
|
|
g_value_set_uint (value, priv->anchor);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER:
|
|
g_value_set_uint (value, priv->layer);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY:
|
|
g_value_set_boolean (value, priv->kbd_interactivity);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE:
|
|
g_value_set_int (value, priv->exclusive_zone);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP:
|
|
g_value_set_int (value, priv->margin_top);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM:
|
|
g_value_set_int (value, priv->margin_bottom);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT:
|
|
g_value_set_int (value, priv->margin_left);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT:
|
|
g_value_set_int (value, priv->margin_right);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH:
|
|
g_value_set_uint (value, priv->width);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT:
|
|
g_value_set_uint (value, priv->height);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_CONFIGURED_WIDTH:
|
|
g_value_set_uint (value, priv->configured_width);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_CONFIGURED_HEIGHT:
|
|
g_value_set_uint (value, priv->configured_height);
|
|
break;
|
|
case PHOSH_LAYER_SURFACE_PROP_NAMESPACE:
|
|
g_value_set_string (value, priv->namespace);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_realize (GtkWidget *widget)
|
|
{
|
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (widget);
|
|
PhoshLayerSurfacePrivate *priv;
|
|
GdkWindow *gdk_window;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
GTK_WIDGET_CLASS (phosh_layer_surface_parent_class)->realize (widget);
|
|
|
|
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
|
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
|
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
|
|
|
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
|
}
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_map (GtkWidget *widget)
|
|
{
|
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (widget);
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
GTK_WIDGET_CLASS (phosh_layer_surface_parent_class)->map (widget);
|
|
|
|
if (!priv->wl_surface) {
|
|
GdkWindow *gdk_window;
|
|
|
|
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
|
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
|
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
|
}
|
|
g_debug ("Mapped %p, namespace: %s", priv->wl_surface, priv->namespace);
|
|
|
|
priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface (priv->layer_shell,
|
|
priv->wl_surface,
|
|
priv->wl_output,
|
|
priv->layer,
|
|
priv->namespace);
|
|
zwlr_layer_surface_v1_set_exclusive_zone (priv->layer_surface, priv->exclusive_zone);
|
|
zwlr_layer_surface_v1_set_size (priv->layer_surface, priv->width, priv->height);
|
|
zwlr_layer_surface_v1_set_anchor (priv->layer_surface, priv->anchor);
|
|
zwlr_layer_surface_v1_set_margin (priv->layer_surface,
|
|
priv->margin_top,
|
|
priv->margin_right,
|
|
priv->margin_bottom,
|
|
priv->margin_left);
|
|
zwlr_layer_surface_v1_set_keyboard_interactivity (priv->layer_surface, priv->kbd_interactivity);
|
|
zwlr_layer_surface_v1_add_listener (priv->layer_surface,
|
|
&layer_surface_listener,
|
|
self);
|
|
wl_surface_commit (priv->wl_surface);
|
|
|
|
/* Process all pending events, otherwise we end up sending ack configure
|
|
* to a not yet configured surface */
|
|
wl_display_roundtrip (gdk_wayland_display_get_wl_display (gdk_display_get_default ()));
|
|
}
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_unmap (GtkWidget *widget)
|
|
{
|
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (widget);
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
g_clear_pointer (&priv->layer_surface, zwlr_layer_surface_v1_destroy);
|
|
priv->wl_surface = NULL;
|
|
|
|
GTK_WIDGET_CLASS (phosh_layer_surface_parent_class)->unmap (widget);
|
|
}
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_dispose (GObject *object)
|
|
{
|
|
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
|
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
g_clear_pointer (&priv->layer_surface, zwlr_layer_surface_v1_destroy);
|
|
g_clear_pointer (&priv->namespace, g_free);
|
|
|
|
G_OBJECT_CLASS (phosh_layer_surface_parent_class)->dispose (object);
|
|
}
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_class_init (PhoshLayerSurfaceClass *klass)
|
|
{
|
|
GObjectClass *object_class = (GObjectClass *)klass;
|
|
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
|
|
|
|
object_class->dispose = phosh_layer_surface_dispose;
|
|
object_class->set_property = phosh_layer_surface_set_property;
|
|
object_class->get_property = phosh_layer_surface_get_property;
|
|
|
|
widget_class->realize = phosh_layer_surface_realize;
|
|
widget_class->map = phosh_layer_surface_map;
|
|
widget_class->unmap = phosh_layer_surface_unmap;
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_LAYER_SHELL] =
|
|
g_param_spec_pointer (
|
|
"layer-shell",
|
|
"Wayland Layer Shell Global",
|
|
"The layer shell wayland global",
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_WL_OUTPUT] =
|
|
g_param_spec_pointer (
|
|
"wl-output",
|
|
"Wayland Output",
|
|
"The wl_output associated with this surface",
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_ANCHOR] =
|
|
g_param_spec_uint (
|
|
"anchor",
|
|
"Anchor edges",
|
|
"The edges to anchor the surface to",
|
|
0,
|
|
G_MAXUINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_LAYER] =
|
|
g_param_spec_uint (
|
|
"layer",
|
|
"Layer",
|
|
"The layer the surface should be attached to",
|
|
0,
|
|
G_MAXUINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY] =
|
|
g_param_spec_boolean (
|
|
"kbd-interactivity",
|
|
"Keyboard interactivity",
|
|
"Whether the surface interacts with the keyboard",
|
|
FALSE,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE] =
|
|
g_param_spec_int (
|
|
"exclusive-zone",
|
|
"Exclusive Zone",
|
|
"Set area that is not occluded with other surfaces",
|
|
-1,
|
|
G_MAXINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT] =
|
|
g_param_spec_int (
|
|
"margin-left",
|
|
"Left margin",
|
|
"Distance away from the left anchor point",
|
|
G_MININT,
|
|
G_MAXINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT] =
|
|
g_param_spec_int (
|
|
"margin-right",
|
|
"Right margin",
|
|
"Distance away from the right anchor point",
|
|
G_MININT,
|
|
G_MAXINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP] =
|
|
g_param_spec_int (
|
|
"margin-top",
|
|
"Top margin",
|
|
"Distance away from the top anchor point",
|
|
G_MININT,
|
|
G_MAXINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM] =
|
|
g_param_spec_int (
|
|
"margin-bottom",
|
|
"Bottom margin",
|
|
"Distance away from the bottom anchor point",
|
|
G_MININT,
|
|
G_MAXINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH] =
|
|
g_param_spec_uint (
|
|
"width",
|
|
"Width",
|
|
"The width of the layer surface",
|
|
0,
|
|
G_MAXUINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT] =
|
|
g_param_spec_uint (
|
|
"height",
|
|
"Height",
|
|
"The height of the layer surface",
|
|
0,
|
|
G_MAXUINT,
|
|
0,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_CONFIGURED_WIDTH] =
|
|
g_param_spec_uint (
|
|
"configured-width",
|
|
"Configured width",
|
|
"The width of the layer surface set by the compositor",
|
|
0,
|
|
G_MAXUINT,
|
|
0,
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_CONFIGURED_HEIGHT] =
|
|
g_param_spec_uint (
|
|
"configured-height",
|
|
"Configured height",
|
|
"The height of the layer surface set by the compositor",
|
|
0,
|
|
G_MAXUINT,
|
|
0,
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
props[PHOSH_LAYER_SURFACE_PROP_NAMESPACE] =
|
|
g_param_spec_string (
|
|
"namespace",
|
|
"Namespace",
|
|
"Namespace of the layer surface",
|
|
"",
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
|
|
|
g_object_class_install_properties (object_class, PHOSH_LAYER_SURFACE_PROP_LAST_PROP, props);
|
|
|
|
/**
|
|
* PhoshLayerSurface::configured
|
|
* @self: The #PhoshLayerSurface instance.
|
|
*
|
|
* This signal is emitted once we received the configure event from the
|
|
* compositor.
|
|
*/
|
|
signals[CONFIGURED] =
|
|
g_signal_new ("configured",
|
|
G_TYPE_FROM_CLASS (klass),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (PhoshLayerSurfaceClass, configured),
|
|
NULL, NULL, NULL,
|
|
G_TYPE_NONE, 0);
|
|
}
|
|
|
|
|
|
static void
|
|
phosh_layer_surface_init (PhoshLayerSurface *self)
|
|
{
|
|
}
|
|
|
|
|
|
GtkWidget *
|
|
phosh_layer_surface_new (gpointer layer_shell,
|
|
gpointer wl_output)
|
|
{
|
|
return g_object_new (PHOSH_TYPE_LAYER_SURFACE,
|
|
"layer-shell", layer_shell,
|
|
"wl-output", wl_output,
|
|
NULL);
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_get_surface:
|
|
* @self: The #PhoshLayerSurface
|
|
*
|
|
* Get the layer layer surface or #NULL if the window
|
|
* is not yet realized.
|
|
*/
|
|
struct zwlr_layer_surface_v1 *
|
|
phosh_layer_surface_get_layer_surface (PhoshLayerSurface *self)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), NULL);
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
return priv->layer_surface;
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_get_wl_surface:
|
|
* @self: The #PhoshLayerSurface
|
|
*
|
|
* Get the layer wayland surface or #NULL if the window
|
|
* is not yet realized.
|
|
*/
|
|
struct wl_surface *
|
|
phosh_layer_surface_get_wl_surface (PhoshLayerSurface *self)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), NULL);
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
return priv->wl_surface;
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_set_size:
|
|
* @self: The #PhoshLayerSurface
|
|
* @width: the height in pixels
|
|
* @height: the width in pixels
|
|
*
|
|
* Set the size of a layer surface. A value of '-1' indicates 'use old value'
|
|
*/
|
|
void
|
|
phosh_layer_surface_set_size (PhoshLayerSurface *self, int width, int height)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
int old_width, old_height;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
if (priv->height == height && priv->width == width)
|
|
return;
|
|
|
|
old_width = priv->width;
|
|
old_height = priv->height;
|
|
|
|
if (width != -1)
|
|
priv->width = width;
|
|
|
|
if (height != -1)
|
|
priv->height = height;
|
|
|
|
if (gtk_widget_get_mapped (GTK_WIDGET (self))) {
|
|
zwlr_layer_surface_v1_set_size (priv->layer_surface, priv->width, priv->height);
|
|
}
|
|
|
|
if (priv->height != old_height)
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]);
|
|
|
|
if (priv->width != old_width)
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]);
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_set_margins:
|
|
* @self: The #PhoshLayerSurface
|
|
* @top: the top margin in pixels
|
|
* @right: the right margin in pixels
|
|
* @bottom: the bottom margin in pixels
|
|
* @left: the left margin in pixels
|
|
*
|
|
* Set anchor margins of a layer surface.
|
|
*/
|
|
void
|
|
phosh_layer_surface_set_margins (PhoshLayerSurface *self, int top, int right, int bottom, int left)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
int old_top, old_bottom, old_left, old_right;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
old_top = priv->margin_top;
|
|
old_left = priv->margin_left;
|
|
old_right = priv->margin_right;
|
|
old_bottom = priv->margin_bottom;
|
|
|
|
if (old_top == top && old_left == left && old_right == right && old_bottom == bottom)
|
|
return;
|
|
|
|
priv->margin_top = top;
|
|
priv->margin_left = left;
|
|
priv->margin_right = right;
|
|
priv->margin_bottom = bottom;
|
|
|
|
if (priv->layer_surface)
|
|
zwlr_layer_surface_v1_set_margin (priv->layer_surface, top, right, bottom, left);
|
|
|
|
if (old_top != top)
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP]);
|
|
if (old_bottom != bottom)
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM]);
|
|
if (old_left != left)
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT]);
|
|
if (old_right != right)
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT]);
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_set_exclusive_zone:
|
|
* @self: The #PhoshLayerSurface
|
|
* @zone: Size of the exclusive zone.
|
|
*
|
|
* Set exclusive zone of a layer surface.
|
|
*/
|
|
void
|
|
phosh_layer_surface_set_exclusive_zone (PhoshLayerSurface *self, int zone)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
int old_zone;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
old_zone = priv->exclusive_zone;
|
|
|
|
if (old_zone == zone)
|
|
return;
|
|
|
|
priv->exclusive_zone = zone;
|
|
|
|
if (priv->layer_surface)
|
|
zwlr_layer_surface_v1_set_exclusive_zone (priv->layer_surface, zone);
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE]);
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_set_keyboard_interactivity:
|
|
* @self: The #PhoshLayerSurface
|
|
* @interactivity: %TRUE if the #PhoshLayerSurface should receive keyboard input.
|
|
*
|
|
* Set keyboard ineractivity a layer surface.
|
|
*/
|
|
void
|
|
phosh_layer_surface_set_kbd_interactivity (PhoshLayerSurface *self, gboolean interactivity)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
if (priv->kbd_interactivity == interactivity)
|
|
return;
|
|
|
|
priv->kbd_interactivity = interactivity;
|
|
|
|
if (priv->layer_surface)
|
|
zwlr_layer_surface_v1_set_keyboard_interactivity (priv->layer_surface, interactivity);
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY]);
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_set_layer:
|
|
* @self: The #PhoshLayerSurface
|
|
* @layer: The layer.
|
|
*
|
|
* Sets the layer a layer-surface belongs to `layer`.
|
|
*/
|
|
void
|
|
phosh_layer_surface_set_layer (PhoshLayerSurface *self, guint32 layer)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
if (priv->layer == layer)
|
|
return;
|
|
|
|
priv->layer = layer;
|
|
|
|
if (priv->layer_surface)
|
|
zwlr_layer_surface_v1_set_layer (priv->layer_surface, layer);
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER]);
|
|
}
|
|
|
|
|
|
/**
|
|
* phosh_layer_surface_wl_surface_commit:
|
|
* @self: The #PhoshLayerSurface
|
|
*
|
|
* Forces a commit of layer surface's state.
|
|
*/
|
|
void
|
|
phosh_layer_surface_wl_surface_commit (PhoshLayerSurface *self)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
if (priv->wl_surface)
|
|
wl_surface_commit (priv->wl_surface);
|
|
}
|
|
|
|
|
|
void
|
|
phosh_layer_surface_get_margins (PhoshLayerSurface *self, int *top, int *right, int *bottom, int *left)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
if (top)
|
|
*top = priv->margin_top;
|
|
|
|
if (right)
|
|
*right = priv->margin_right;
|
|
|
|
if (bottom)
|
|
*bottom = priv->margin_bottom;
|
|
|
|
if (left)
|
|
*left = priv->margin_left;
|
|
}
|
|
|
|
|
|
int
|
|
phosh_layer_surface_get_configured_width (PhoshLayerSurface *self)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), 0);
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
return priv->configured_width;
|
|
}
|
|
|
|
|
|
int
|
|
phosh_layer_surface_get_configured_height (PhoshLayerSurface *self)
|
|
{
|
|
PhoshLayerSurfacePrivate *priv;
|
|
|
|
g_return_val_if_fail (PHOSH_IS_LAYER_SURFACE (self), 0);
|
|
priv = phosh_layer_surface_get_instance_private (self);
|
|
|
|
return priv->configured_height;
|
|
}
|