[gtk/present-toplevel-2: 2/59] Introduce GdkToplevel
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/present-toplevel-2: 2/59] Introduce GdkToplevel
- Date: Thu, 12 Mar 2020 18:57:34 +0000 (UTC)
commit dfbde3da4f53b750c2dbe321ac1b70f6063241fa
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Feb 29 10:07:43 2020 -0500
Introduce GdkToplevel
This is a new interface for toplevel surfaces.
gdk/gdk.h | 12 +-
gdk/gdksurface.c | 268 ++++++++++++++++++++++--
gdk/gdktoplevel.c | 518 +++++++++++++++++++++++++++++++++++++++++++++++
gdk/gdktoplevel.h | 108 ++++++++++
gdk/gdktoplevelprivate.h | 48 +++++
gdk/meson.build | 2 +
6 files changed, 936 insertions(+), 20 deletions(-)
---
diff --git a/gdk/gdk.h b/gdk/gdk.h
index a4f434511e..30ab0d7590 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -27,12 +27,11 @@
#define __GDK_H_INSIDE__
-#include <gdk/gdkconfig.h>
-#include <gdk/gdkversionmacros.h>
#include <gdk/gdkapplaunchcontext.h>
#include <gdk/gdkcairo.h>
#include <gdk/gdkcairocontext.h>
#include <gdk/gdkclipboard.h>
+#include <gdk/gdkconfig.h>
#include <gdk/gdkcontentdeserializer.h>
#include <gdk/gdkcontentformats.h>
#include <gdk/gdkcontentprovider.h>
@@ -60,16 +59,19 @@
#include <gdk/gdkpaintable.h>
#include <gdk/gdkpango.h>
#include <gdk/gdkpixbuf.h>
+#include <gdk/gdkpopup.h>
+#include <gdk/gdkpopuplayout.h>
#include <gdk/gdkrectangle.h>
#include <gdk/gdkrgba.h>
#include <gdk/gdkseat.h>
#include <gdk/gdksnapshot.h>
+#include <gdk/gdksurface.h>
#include <gdk/gdktexture.h>
+#include <gdk/gdktoplevel.h>
+#include <gdk/gdktoplevellayout.h>
#include <gdk/gdktypes.h>
+#include <gdk/gdkversionmacros.h>
#include <gdk/gdkvulkancontext.h>
-#include <gdk/gdksurface.h>
-#include <gdk/gdkpopup.h>
-#include <gdk/gdktoplevellayout.h>
#include <gdk/gdk-autocleanup.h>
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 70a62487d2..6b822ffb2f 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -40,6 +40,7 @@
#include "gdkmarshalers.h"
#include "gdkpopupprivate.h"
#include "gdkrectangle.h"
+#include "gdktoplevelprivate.h"
#include <math.h>
@@ -83,7 +84,6 @@ enum {
PROP_CURSOR,
PROP_DISPLAY,
PROP_FRAME_CLOCK,
- PROP_STATE,
PROP_MAPPED,
LAST_PROP
};
@@ -112,10 +112,13 @@ static guint signals[LAST_SIGNAL] = { 0 };
static GParamSpec *properties[LAST_PROP] = { NULL, };
static void gdk_surface_popup_init (GdkPopupInterface *iface);
+static void gdk_surface_toplevel_init (GdkToplevelInterface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GdkSurface, gdk_surface, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_POPUP,
- gdk_surface_popup_init))
+ gdk_surface_popup_init)
+ G_IMPLEMENT_INTERFACE (GDK_TYPE_TOPLEVEL,
+ gdk_surface_toplevel_init))
static gboolean
gdk_surface_real_beep (GdkSurface *surface)
@@ -443,13 +446,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
GDK_TYPE_FRAME_CLOCK,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- properties[PROP_STATE] =
- g_param_spec_flags ("state",
- P_("State"),
- P_("State"),
- GDK_TYPE_SURFACE_STATE, GDK_SURFACE_STATE_WITHDRAWN,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
properties[PROP_MAPPED] =
g_param_spec_boolean ("mapped",
P_("Mapped"),
@@ -466,6 +462,7 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
g_object_class_install_properties (object_class, LAST_PROP, properties);
gdk_popup_install_properties (object_class, LAST_PROP);
+ gdk_toplevel_install_properties (object_class, LAST_PROP + GDK_POPUP_NUM_PROPERTIES);
/**
* GdkSurface::popup-layout-changed
@@ -644,12 +641,81 @@ gdk_surface_set_property (GObject *object,
surface->autohide = g_value_get_boolean (value);
break;
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_TITLE:
+ gdk_surface_set_title (surface, g_value_get_string (value));
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_STARTUP_ID:
+ gdk_surface_set_startup_id (surface, g_value_get_string (value));
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_TRANSIENT_FOR:
+ gdk_surface_set_transient_for (surface, g_value_get_object (value));
+ break;
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_MODAL:
+ GDK_SURFACE_GET_CLASS (surface)->set_modal_hint (surface, g_value_get_boolean (value));
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_ICON_LIST:
+ gdk_surface_set_icon_list (surface, g_value_get_pointer (value));
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_STICKY:
+ if (g_value_get_boolean (value))
+ GDK_SURFACE_GET_CLASS (surface)->stick (surface);
+ else
+ GDK_SURFACE_GET_CLASS (surface)->unstick (surface);
+ g_object_notify_by_pspec (G_OBJECT (surface), pspec);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_KEEP_ABOVE:
+ GDK_SURFACE_GET_CLASS (surface)->set_keep_above (surface, g_value_get_boolean (value));
+ g_object_notify_by_pspec (G_OBJECT (surface), pspec);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_KEEP_BELOW:
+ GDK_SURFACE_GET_CLASS (surface)->set_keep_below (surface, g_value_get_boolean (value));
+ g_object_notify_by_pspec (G_OBJECT (surface), pspec);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_ACCEPT_FOCUS:
+ if (surface->accept_focus != g_value_get_boolean (value))
+ {
+ surface->accept_focus = g_value_get_boolean (value);
+ GDK_SURFACE_GET_CLASS (surface)->set_accept_focus (surface, surface->accept_focus);
+ g_object_notify_by_pspec (G_OBJECT (surface), pspec);
+ }
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_FOCUS_ON_MAP:
+ if (surface->focus_on_map != g_value_get_boolean (value))
+ {
+ surface->focus_on_map = g_value_get_boolean (value);
+ GDK_SURFACE_GET_CLASS (surface)->set_focus_on_map (surface, surface->focus_on_map);
+ g_object_notify_by_pspec (G_OBJECT (surface), pspec);
+ }
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_DECORATED:
+ GDK_SURFACE_GET_CLASS (surface)->set_decorations (surface, g_value_get_boolean (value) ? GDK_DECOR_ALL
: 0);
+ g_object_notify_by_pspec (G_OBJECT (surface), pspec);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_DELETABLE:
+ GDK_SURFACE_GET_CLASS (surface)->set_functions (surface, g_value_get_boolean (value) ? GDK_FUNC_ALL :
GDK_FUNC_ALL | GDK_FUNC_CLOSE);
+ g_object_notify_by_pspec (G_OBJECT (surface), pspec);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+#define GDK_SURFACE_IS_STICKY(surface) (((surface)->state & GDK_SURFACE_STATE_STICKY))
+#define GDK_SURFACE_IS_ABOVE(surface) (((surface)->state & GDK_SURFACE_STATE_ABOVE))
+#define GDK_SURFACE_IS_BELOW(surface) (((surface)->state & GDK_SURFACE_STATE_BELOW))
+
static void
gdk_surface_get_property (GObject *object,
guint prop_id,
@@ -672,10 +738,6 @@ gdk_surface_get_property (GObject *object,
g_value_set_object (value, surface->frame_clock);
break;
- case PROP_STATE:
- g_value_set_flags (value, surface->state);
- break;
-
case PROP_MAPPED:
g_value_set_boolean (value, GDK_SURFACE_IS_MAPPED (surface));
break;
@@ -692,6 +754,58 @@ gdk_surface_get_property (GObject *object,
g_value_set_boolean (value, surface->autohide);
break;
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_STATE:
+ g_value_set_flags (value, surface->state);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_TITLE:
+ g_value_set_string (value, ""); // FIXME
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_STARTUP_ID:
+ g_value_set_string (value, ""); // FIXME
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_TRANSIENT_FOR:
+ g_value_set_object (value, NULL); // FIXME
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_MODAL:
+ g_value_set_boolean (value, surface->modal_hint);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_ICON_LIST:
+ g_value_set_pointer (value, NULL); // FIXME
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_STICKY:
+ g_value_set_boolean (value, GDK_SURFACE_IS_STICKY (surface));
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_KEEP_ABOVE:
+ g_value_set_boolean (value, GDK_SURFACE_IS_ABOVE (surface));
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_KEEP_BELOW:
+ g_value_set_boolean (value, GDK_SURFACE_IS_BELOW (surface));
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_ACCEPT_FOCUS:
+ g_value_set_boolean (value, surface->accept_focus);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_FOCUS_ON_MAP:
+ g_value_set_boolean (value, surface->focus_on_map);
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_DECORATED:
+ g_value_set_boolean (value, FALSE); // FIXME
+ break;
+
+ case LAST_PROP + GDK_POPUP_NUM_PROPERTIES + GDK_TOPLEVEL_PROP_DELETABLE:
+ g_value_set_boolean (value, FALSE); // FIXME
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -867,7 +981,8 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface,
surface_remove_from_pointer_info (surface, surface->display);
- g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
+ if (GDK_IS_TOPLEVEL (surface))
+ g_object_notify (G_OBJECT (surface), "state");
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
}
@@ -2078,6 +2193,116 @@ gdk_surface_popup_init (GdkPopupInterface *iface)
iface->get_position_y = gdk_popup_surface_get_position_y;
}
+static gboolean
+gdk_toplevel_surface_present (GdkToplevel *toplevel,
+ int width,
+ int height,
+ GdkToplevelLayout *layout)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+ GdkGeometry geometry;
+ GdkSurfaceHints mask;
+
+ g_return_val_if_fail (surface->surface_type == GDK_SURFACE_TOPLEVEL, FALSE);
+ g_return_val_if_fail (!GDK_SURFACE_DESTROYED (surface), FALSE);
+
+ GDK_SURFACE_GET_CLASS (surface)->unminimize (surface);
+
+ if (gdk_toplevel_layout_get_resizable (layout))
+ {
+ geometry.min_width = gdk_toplevel_layout_get_min_width (layout);
+ geometry.min_height = gdk_toplevel_layout_get_min_height (layout);
+ mask = GDK_HINT_MIN_SIZE;
+ }
+ else
+ {
+ geometry.max_width = geometry.min_width = width;
+ geometry.max_height = geometry.min_height = height;
+ mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
+ }
+
+ GDK_SURFACE_GET_CLASS (surface)->set_geometry_hints (surface, &geometry, mask);
+ gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
+ GDK_SURFACE_GET_CLASS (surface)->toplevel_resize (surface, width, height);
+
+ if (gdk_toplevel_layout_get_maximized (layout))
+ gdk_surface_maximize (surface);
+ else
+ gdk_surface_unmaximize (surface);
+
+ if (gdk_toplevel_layout_get_fullscreen (layout))
+ {
+ GdkMonitor *monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
+ if (monitor)
+ GDK_SURFACE_GET_CLASS (surface)->fullscreen_on_monitor (surface, monitor);
+ else
+ GDK_SURFACE_GET_CLASS (surface)->fullscreen (surface);
+ }
+ else
+ GDK_SURFACE_GET_CLASS (surface)->unfullscreen (surface);
+
+
+ gdk_surface_show_internal (surface, TRUE);
+
+ return TRUE;
+}
+
+static gboolean
+gdk_toplevel_surface_minimize (GdkToplevel *toplevel)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+
+ g_return_val_if_fail (surface->surface_type == GDK_SURFACE_TOPLEVEL, FALSE);
+
+ GDK_SURFACE_GET_CLASS (surface)->minimize (surface);
+
+ return TRUE;
+}
+
+static gboolean
+gdk_toplevel_surface_lower (GdkToplevel *toplevel)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+
+ g_return_val_if_fail (surface->surface_type == GDK_SURFACE_TOPLEVEL, FALSE);
+
+ GDK_SURFACE_GET_CLASS (surface)->lower (surface);
+
+ return TRUE;
+}
+
+static void
+gdk_toplevel_surface_focus (GdkToplevel *toplevel,
+ guint32 timestamp)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+
+ g_return_if_fail (surface->surface_type == GDK_SURFACE_TOPLEVEL);
+
+ GDK_SURFACE_GET_CLASS (surface)->focus (surface, timestamp);
+}
+
+static gboolean
+gdk_toplevel_surface_show_window_menu (GdkToplevel *toplevel,
+ GdkEvent *event)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+
+ g_return_val_if_fail (surface->surface_type == GDK_SURFACE_TOPLEVEL, FALSE);
+
+ return GDK_SURFACE_GET_CLASS (surface)->show_window_menu (surface, event);
+}
+
+static void
+gdk_surface_toplevel_init (GdkToplevelInterface *iface)
+{
+ iface->present = gdk_toplevel_surface_present;
+ iface->minimize = gdk_toplevel_surface_minimize;
+ iface->lower = gdk_toplevel_surface_lower;
+ iface->focus = gdk_toplevel_surface_focus;
+ iface->show_window_menu = gdk_toplevel_surface_show_window_menu;
+}
+
static void
gdk_surface_set_cursor_internal (GdkSurface *surface,
GdkDevice *device,
@@ -2867,6 +3092,8 @@ gdk_surface_set_startup_id (GdkSurface *surface,
const gchar *startup_id)
{
GDK_SURFACE_GET_CLASS (surface)->set_startup_id (surface, startup_id);
+
+ g_object_notify (G_OBJECT (surface), "startup-id");
}
/**
@@ -2889,6 +3116,8 @@ gdk_surface_set_transient_for (GdkSurface *surface,
surface->transient_for = parent;
GDK_SURFACE_GET_CLASS (surface)->set_transient_for (surface, parent);
+
+ g_object_notify (G_OBJECT (surface), "transient-for");
}
/**
@@ -2951,6 +3180,8 @@ gdk_surface_set_icon_list (GdkSurface *surface,
GList *textures)
{
GDK_SURFACE_GET_CLASS (surface)->set_icon_list (surface, textures);
+
+ g_object_notify (G_OBJECT (surface), "icon-list");
}
/**
@@ -3790,6 +4021,7 @@ gdk_surface_set_state (GdkSurface *surface,
GdkSurfaceState new_state)
{
gboolean was_mapped, mapped;
+ gboolean was_sticky, sticky;
g_return_if_fail (GDK_IS_SURFACE (surface));
if (new_state == surface->state)
@@ -3801,17 +4033,23 @@ gdk_surface_set_state (GdkSurface *surface,
*/
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
+ was_sticky = GDK_SURFACE_IS_STICKY (surface);
surface->state = new_state;
mapped = GDK_SURFACE_IS_MAPPED (surface);
+ sticky = GDK_SURFACE_IS_STICKY (surface);
_gdk_surface_update_viewable (surface);
- g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_STATE]);
+ if (GDK_IS_TOPLEVEL (surface))
+ g_object_notify (G_OBJECT (surface), "state");
if (was_mapped != mapped)
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
+
+ if (was_sticky != sticky)
+ g_object_notify (G_OBJECT (surface), "sticky");
}
void
diff --git a/gdk/gdktoplevel.c b/gdk/gdktoplevel.c
new file mode 100644
index 0000000000..c2c64f368e
--- /dev/null
+++ b/gdk/gdktoplevel.c
@@ -0,0 +1,518 @@
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include "gdkintl.h"
+#include "gdk-private.h"
+#include "gdktoplevelprivate.h"
+
+/**
+ * SECTION:gdktoplevel
+ * @Short_description: Interface for toplevel surfaces
+ * @Title: Toplevels
+ *
+ * A #GdkToplevel is a freestanding toplevel surface.
+ */
+
+
+/* FIXME: this can't have GdkSurface as a prerequisite
+ * as long as GdkSurface implements this interface itself
+ */
+G_DEFINE_INTERFACE (GdkToplevel, gdk_toplevel, G_TYPE_OBJECT)
+
+static gboolean
+gdk_toplevel_default_present (GdkToplevel *toplevel,
+ int width,
+ int height,
+ GdkToplevelLayout *layout)
+{
+ return FALSE;
+}
+
+static gboolean
+gdk_toplevel_default_minimize (GdkToplevel *toplevel)
+{
+ return FALSE;
+}
+
+static gboolean
+gdk_toplevel_default_lower (GdkToplevel *toplevel)
+{
+ return FALSE;
+}
+
+static void
+gdk_toplevel_default_focus (GdkToplevel *toplevel,
+ guint32 timestamp)
+{
+}
+
+static gboolean
+gdk_toplevel_default_show_window_menu (GdkToplevel *toplevel,
+ GdkEvent *event)
+{
+ return FALSE;
+}
+
+static void
+gdk_toplevel_default_init (GdkToplevelInterface *iface)
+{
+ iface->present = gdk_toplevel_default_present;
+ iface->minimize = gdk_toplevel_default_minimize;
+ iface->lower = gdk_toplevel_default_lower;
+ iface->focus = gdk_toplevel_default_focus;
+ iface->show_window_menu = gdk_toplevel_default_show_window_menu;
+
+ g_object_interface_install_property (iface,
+ g_param_spec_flags ("state",
+ P_("State"),
+ P_("State"),
+ GDK_TYPE_SURFACE_STATE, GDK_SURFACE_STATE_WITHDRAWN,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("title",
+ "Title",
+ "The title of the surface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("startup-id",
+ "Startup ID",
+ "The startup ID of the surface",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_object ("transient-for",
+ "Transient For",
+ "The transient parent of the surface",
+ GDK_TYPE_SURFACE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("modal",
+ "Modal",
+ "Whether the surface is modal",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_pointer ("icon-list",
+ "Icon List",
+ "The list of icon textures",
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("sticky",
+ "Sticky",
+ "Whether the surface is on all workspaces",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("keep-above",
+ "Keep above",
+ "Whether the surface is on above all other surfaces",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("keep-below",
+ "Keep below",
+ "Whether the surface is below all other surfaces",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("accept-focus",
+ "Accept focus",
+ "Whether the surface should accept keyboard focus",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("focus-on-map",
+ "Focus on map",
+ "Whether the surface should receive keyboard focus on map",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("decorated",
+ "Decorated",
+ "Decorated",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("deletable",
+ "Deletable",
+ "Deletable",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
+}
+
+guint
+gdk_toplevel_install_properties (GObjectClass *object_class,
+ guint first_prop)
+{
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_STATE, "state");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_TITLE, "title");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_STARTUP_ID, "startup-id");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_TRANSIENT_FOR,
"transient-for");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_MODAL, "modal");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_ICON_LIST, "icon-list");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_STICKY, "sticky");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_KEEP_ABOVE, "keep-above");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_KEEP_BELOW, "keep-below");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_ACCEPT_FOCUS,
"accept-focus");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_FOCUS_ON_MAP,
"focus-on-map");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_DECORATED, "decorated");
+ g_object_class_override_property (object_class, first_prop + GDK_TOPLEVEL_PROP_DELETABLE, "deletable");
+
+ return GDK_TOPLEVEL_NUM_PROPERTIES;
+}
+
+/**
+ * gdk_toplevel_present:
+ * @toplevel: the #GdkToplevel to show
+ * @width: the unconstrained toplevel width to layout
+ * @height: the unconstrained toplevel height to layout
+ * @layout: the #GdkToplevelLayout object used to layout
+ *
+ * Present @toplevel after having processed the #GdkToplevelLayout rules.
+ * If the toplevel was previously now showing, it will be showed,
+ * otherwise it will change layout according to @layout.
+ *
+ * Presenting may fail.
+ *
+ * Returns: %FALSE if @toplevel failed to be presented, otherwise %TRUE.
+ */
+gboolean
+gdk_toplevel_present (GdkToplevel *toplevel,
+ int width,
+ int height,
+ GdkToplevelLayout *layout)
+{
+ g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
+ g_return_val_if_fail (width > 0, FALSE);
+ g_return_val_if_fail (height > 0, FALSE);
+ g_return_val_if_fail (layout != NULL, FALSE);
+
+ return GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, width, height, layout);
+}
+
+/**
+ * gdk_toplevel_minimize:
+ * @toplevel: a #GdkToplevel
+ *
+ * Asks to minimize the @toplevel.
+ *
+ * The windowing system may choose to ignore the request.
+ *
+ * Returns: %TRUE if the surface was minimized
+ */
+gboolean
+gdk_toplevel_minimize (GdkToplevel *toplevel)
+{
+ g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
+
+ return GDK_TOPLEVEL_GET_IFACE (toplevel)->minimize (toplevel);
+}
+
+/**
+ * gdk_toplevel_lower:
+ * @toplevel: a #GdkToplevel
+ *
+ * Asks to lower the @toplevel below other windows.
+ *
+ * The windowing system may choose to ignore the request.
+ *
+ * Returns: %TRUE if the surface was lowered
+ */
+gboolean
+gdk_toplevel_lower (GdkToplevel *toplevel)
+{
+ g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
+
+ return GDK_TOPLEVEL_GET_IFACE (toplevel)->lower (toplevel);
+}
+
+/**
+ * gdk_toplevel_focus:
+ * @toplevel: a #GdkToplevel
+ * @timestamp: timestamp of the event triggering the surface focus
+ *
+ * Sets keyboard focus to @surface.
+ *
+ * In most cases, gtk_window_present_with_time() should be used
+ * on a #GtkWindow, rather than calling this function.
+ */
+void
+gdk_toplevel_focus (GdkToplevel *toplevel,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ return GDK_TOPLEVEL_GET_IFACE (toplevel)->focus (toplevel, timestamp);
+}
+
+/**
+ * gdk_toplevel_get_state:
+ * @toplevel: a #GdkToplevel
+ *
+ * Gets the bitwise OR of the currently active surface state flags,
+ * from the #GdkSurfaceState enumeration.
+ *
+ * Returns: surface state bitfield
+ */
+GdkSurfaceState
+gdk_toplevel_get_state (GdkToplevel *toplevel)
+{
+ GdkSurfaceState state;
+
+ g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), 0);
+
+ g_object_get (toplevel, "state", &state, NULL);
+
+ return state;
+}
+
+/**
+ * gdk_toplevel_set_title:
+ * @toplevel: a #GdkToplevel
+ * @title: title of @surface
+ *
+ * Sets the title of a toplevel surface, to be displayed in the titlebar,
+ * in lists of windows, etc.
+ */
+void
+gdk_toplevel_set_title (GdkToplevel *toplevel,
+ const char *title)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "title", title, NULL);
+}
+
+/**
+ * gdk_toplevel_set_startup_id:
+ * @toplevel: a #GdkToplevel
+ * @startup_id: a string with startup-notification identifier
+ *
+ * When using GTK, typically you should use gtk_window_set_startup_id()
+ * instead of this low-level function.
+ */
+void
+gdk_toplevel_set_startup_id (GdkToplevel *toplevel,
+ const char *startup_id)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "startup-id", startup_id, NULL);
+}
+
+/**
+ * gdk_toplevel_set_transient_for:
+ * @toplevel: a #GdkToplevel
+ * @parent: another toplevel #GdkSurface
+ *
+ * Indicates to the window manager that @surface is a transient dialog
+ * associated with the application surface @parent. This allows the
+ * window manager to do things like center @surface on @parent and
+ * keep @surface above @parent.
+ *
+ * See gtk_window_set_transient_for() if you’re using #GtkWindow or
+ * #GtkDialog.
+ */
+void
+gdk_toplevel_set_transient_for (GdkToplevel *toplevel,
+ GdkSurface *parent)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "transient-for", parent, NULL);
+}
+
+void
+gdk_toplevel_set_modal (GdkToplevel *toplevel,
+ gboolean modal)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "modal", modal, NULL);
+}
+
+/**
+ * gdk_toplevel_set_icon_list:
+ * @toplevel: a #GdkToplevel
+ * @surfaces: (transfer none) (element-type GdkTexture):
+ * A list of textures to use as icon, of different sizes
+ *
+ * Sets a list of icons for the surface.
+ *
+ * One of these will be used to represent the surface in iconic form.
+ * The icon may be shown in window lists or task bars. Which icon
+ * size is shown depends on the window manager. The window manager
+ * can scale the icon but setting several size icons can give better
+ * image quality.
+ *
+ * Note that some platforms don't support surface icons.
+ */
+void
+gdk_toplevel_set_icon_list (GdkToplevel *toplevel,
+ GList *surfaces)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "icon-list", surfaces, NULL);
+}
+
+/**
+ * gdk_toplevel_show_window_menu:
+ * @toplevel: a #GdkToplevel
+ * @event: a #GdkEvent to show the menu for
+ *
+ * Asks the windowing system to show the window menu.
+ *
+ * The window menu is the menu shown when right-clicking the titlebar
+ * on traditional windows managed by the window manager. This is useful
+ * for windows using client-side decorations, activating it with a
+ * right-click on the window decorations.
+ *
+ * Returns: %TRUE if the window menu was shown and %FALSE otherwise.
+ */
+gboolean
+gdk_toplevel_show_window_menu (GdkToplevel *toplevel,
+ GdkEvent *event)
+{
+ g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
+
+ return GDK_TOPLEVEL_GET_IFACE (toplevel)->show_window_menu (toplevel, event);
+}
+
+/**
+ * gdk_toplevel_set_sticky:
+ * @toplevel: a #GdkToplevel
+ * @sticky: whether to make @toplevel show on all workspaces
+ *
+ * Set if @surface is sticky.
+ **/
+void
+gdk_toplevel_set_sticky (GdkToplevel *toplevel,
+ gboolean sticky)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "sticky", sticky, NULL);
+}
+
+/**
+ * gdk_toplevel_set_keep_above:
+ * @toplevel: a #GdkToplevel
+ * @above: whether to keep @toplevel above other surfaces
+ *
+ * Set if @surface must be kept above other surfaces.
+ **/
+void
+gdk_toplevel_set_keep_above (GdkToplevel *toplevel,
+ gboolean above)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "keep-above", above, NULL);
+}
+
+/**
+ * gdk_toplevel_set_keep_below:
+ * @toplevel: a #GdkToplevel
+ * @below: whether to keep @toplevel below other surfaces
+ *
+ * Set if @surface must be kept below other surfaces.
+ **/
+void
+gdk_toplevel_set_keep_below (GdkToplevel *toplevel,
+ gboolean below)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "keep-below", below, NULL);
+}
+
+/**
+ * gdk_toplevel_set_accept_focus:
+ * @toplevel: a #GdkToplevel
+ * @accept_focus: whether @toplevel should accept keyboard focus
+ *
+ * Setting @accept_focus to %FALSE hints the desktop environment
+ * that the surface doesn’t want to receive input focus.
+ */
+void
+gdk_toplevel_set_accept_focus (GdkToplevel *toplevel,
+ gboolean accept_focus)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "accept-focus", accept_focus, NULL);
+}
+
+/**
+ * gdk_toplevel_set_focus_on_map:
+ * @toplevel: a #GdkToplevel
+ * @focus_on_map: whether @toplevel should receive input focus when mapped
+ *
+ * Setting @focus_on_map to %FALSE hints the desktop environment that the
+ * surface doesn’t want to receive input focus when it is mapped.
+ * focus_on_map should be turned off for surfaces that aren’t triggered
+ * interactively (such as popups from network activity).
+ */
+void
+gdk_toplevel_set_focus_on_map (GdkToplevel *toplevel,
+ gboolean focus_on_map)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "focus-on-map", focus_on_map, NULL);
+}
+
+/**
+ * gdk_toplevel_set_decorated:
+ * @toplevel: a #GdkToplevel
+ * @decorated: %TRUE to request decorations
+ *
+ * Setting @decorated to %FALSE hints the desktop environment
+ * that the surface has its own, client-side decorations and
+ * does not need to have window decorations added.
+ */
+void
+gdk_toplevel_set_decorated (GdkToplevel *toplevel,
+ gboolean decorated)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "decorated", decorated, NULL);
+}
+
+/**
+ * gdk_toplevel_set_deletable:
+ * @toplevel: a #GdkToplevel
+ * @deletable: %TRUE to request a delete button
+ *
+ * Setting @deletable to %TRUE hints the desktop environment
+ * that it should offer the user a way to close the surface.
+ */
+void
+gdk_toplevel_set_deletable (GdkToplevel *toplevel,
+ gboolean deletable)
+{
+ g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+
+ g_object_set (toplevel, "deletable", deletable, NULL);
+}
diff --git a/gdk/gdktoplevel.h b/gdk/gdktoplevel.h
new file mode 100644
index 0000000000..e513ad9adf
--- /dev/null
+++ b/gdk/gdktoplevel.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#ifndef __GDK_TOPLEVEL_H__
+#define __GDK_TOPLEVEL_H__
+
+#if !defined(__GDK_H_INSIDE__) && !defined(GTK_COMPILATION)
+#error "Only <gdk/gdk.h> can be included directly."
+#endif
+
+#include <gdk/gdksurface.h>
+#include <gdk/gdktoplevellayout.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_TOPLEVEL (gdk_toplevel_get_type ())
+
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_INTERFACE (GdkToplevel, gdk_toplevel, GDK, TOPLEVEL, GObject)
+
+GDK_AVAILABLE_IN_ALL
+gboolean gdk_toplevel_present (GdkToplevel *toplevel,
+ int width,
+ int height,
+ GdkToplevelLayout *layout);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gdk_toplevel_minimize (GdkToplevel *toplevel);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gdk_toplevel_lower (GdkToplevel *toplevel);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_focus (GdkToplevel *toplevel,
+ guint32 timestamp);
+
+GDK_AVAILABLE_IN_ALL
+GdkSurfaceState gdk_toplevel_get_state (GdkToplevel *toplevel);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_title (GdkToplevel *toplevel,
+ const char *title);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_startup_id (GdkToplevel *toplevel,
+ const char *startup_id);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_transient_for (GdkToplevel *toplevel,
+ GdkSurface *parent);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_modal (GdkToplevel *toplevel,
+ gboolean modal);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_icon_list (GdkToplevel *toplevel,
+ GList *surfaces);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gdk_toplevel_show_window_menu (GdkToplevel *toplevel,
+ GdkEvent *event);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_sticky (GdkToplevel *toplevel,
+ gboolean sticky);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_keep_above (GdkToplevel *toplevel,
+ gboolean above);
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_keep_below (GdkToplevel *toplevel,
+ gboolean below);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_accept_focus (GdkToplevel *toplevel,
+ gboolean accept_focus);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_focus_on_map (GdkToplevel *toplevel,
+ gboolean focus_on_map);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_decorated (GdkToplevel *toplevel,
+ gboolean decorated);
+
+GDK_AVAILABLE_IN_ALL
+void gdk_toplevel_set_deletable (GdkToplevel *toplevel,
+ gboolean deletable);
+G_END_DECLS
+
+#endif /* __GDK_TOPLEVEL_H__ */
diff --git a/gdk/gdktoplevelprivate.h b/gdk/gdktoplevelprivate.h
new file mode 100644
index 0000000000..bd5c9672f3
--- /dev/null
+++ b/gdk/gdktoplevelprivate.h
@@ -0,0 +1,48 @@
+#ifndef __GDK_TOPLEVEL_PRIVATE_H__
+#define __GDK_TOPLEVEL_PRIVATE_H__
+
+#include "gdktoplevel.h"
+
+G_BEGIN_DECLS
+
+
+struct _GdkToplevelInterface
+{
+ GTypeInterface g_iface;
+
+ gboolean (* present) (GdkToplevel *toplevel,
+ int width,
+ int height,
+ GdkToplevelLayout *layout);
+ gboolean (* minimize) (GdkToplevel *toplevel);
+ gboolean (* lower) (GdkToplevel *toplevel);
+ void (* focus) (GdkToplevel *toplevel,
+ guint32 timestamp);
+ gboolean (* show_window_menu) (GdkToplevel *toplevel,
+ GdkEvent *event);
+};
+
+typedef enum
+{
+ GDK_TOPLEVEL_PROP_STATE,
+ GDK_TOPLEVEL_PROP_TITLE,
+ GDK_TOPLEVEL_PROP_STARTUP_ID,
+ GDK_TOPLEVEL_PROP_TRANSIENT_FOR,
+ GDK_TOPLEVEL_PROP_MODAL,
+ GDK_TOPLEVEL_PROP_ICON_LIST,
+ GDK_TOPLEVEL_PROP_STICKY,
+ GDK_TOPLEVEL_PROP_KEEP_ABOVE,
+ GDK_TOPLEVEL_PROP_KEEP_BELOW,
+ GDK_TOPLEVEL_PROP_ACCEPT_FOCUS,
+ GDK_TOPLEVEL_PROP_FOCUS_ON_MAP,
+ GDK_TOPLEVEL_PROP_DECORATED,
+ GDK_TOPLEVEL_PROP_DELETABLE,
+ GDK_TOPLEVEL_NUM_PROPERTIES
+} GdkToplevelProperties;
+
+guint gdk_toplevel_install_properties (GObjectClass *object_class,
+ guint first_prop);
+
+G_END_DECLS
+
+#endif /* __GDK_TOPLEVEL_PRIVATE_H__ */
diff --git a/gdk/meson.build b/gdk/meson.build
index 27d1bc3cda..0c1a277549 100644
--- a/gdk/meson.build
+++ b/gdk/meson.build
@@ -47,6 +47,7 @@ gdk_public_sources = files([
'gdkprofiler.c',
'gdkpopup.c',
'gdktoplevellayout.c',
+ 'gdktoplevel.c',
])
gdk_public_headers = files([
@@ -93,6 +94,7 @@ gdk_public_headers = files([
'gdkpopuplayout.h',
'gdkpopup.h',
'gdktoplevellayout.h',
+ 'gdktoplevel.h',
])
install_headers(gdk_public_headers, subdir: 'gtk-4.0/gdk/')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]