/* GDK - The GIMP Drawing Kit * Copyright (C) 2020 Red Hat * * 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 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 . * */ #include "config.h" #include "gdktoplevellayout.h" #include "gdkmonitor.h" /** * GdkToplevelLayout: * * The `GdkToplevelLayout` struct contains information that * is necessary to present a sovereign window on screen. * * The `GdkToplevelLayout` struct is necessary for using * [method@Gdk.Toplevel.present]. * * Toplevel surfaces are sovereign windows that can be presented * to the user in various states (maximized, on all workspaces, * etc). */ struct _GdkToplevelLayout { /* < private >*/ grefcount ref_count; guint resizable : 1; guint maximized_valid : 1; guint maximized : 1; guint fullscreen_valid : 1; guint fullscreen : 1; GdkMonitor *fullscreen_monitor; }; G_DEFINE_BOXED_TYPE (GdkToplevelLayout, gdk_toplevel_layout, gdk_toplevel_layout_ref, gdk_toplevel_layout_unref) /** * gdk_toplevel_layout_new: (constructor) * * Create a toplevel layout description. * * Used together with gdk_toplevel_present() to describe * how a toplevel surface should be placed and behave on-screen. * * The size is in ”application pixels”, not * ”device pixels” (see gdk_surface_get_scale_factor()). * * Returns: (transfer full): newly created instance of #GdkToplevelLayout */ GdkToplevelLayout * gdk_toplevel_layout_new (void) { GdkToplevelLayout *layout; layout = g_new0 (GdkToplevelLayout, 1); g_ref_count_init (&layout->ref_count); layout->resizable = TRUE; layout->maximized_valid = FALSE; layout->maximized = FALSE; layout->fullscreen_valid = FALSE; layout->fullscreen = FALSE; layout->fullscreen_monitor = NULL; return layout; } /** * gdk_toplevel_layout_ref: * @layout: a #GdkToplevelLayout * * Increases the reference count of @layout. * * Returns: the same @layout */ GdkToplevelLayout * gdk_toplevel_layout_ref (GdkToplevelLayout *layout) { g_ref_count_inc (&layout->ref_count); return layout; } /** * gdk_toplevel_layout_unref: * @layout: a #GdkToplevelLayout * * Decreases the reference count of @layout. */ void gdk_toplevel_layout_unref (GdkToplevelLayout *layout) { if (g_ref_count_dec (&layout->ref_count)) { g_clear_object (&layout->fullscreen_monitor); g_free (layout); } } /** * gdk_toplevel_layout_copy: * @layout: a #GdkToplevelLayout * * Create a new #GdkToplevelLayout and copy the contents of @layout into it. * * Returns: (transfer full): a copy of @layout. */ GdkToplevelLayout * gdk_toplevel_layout_copy (GdkToplevelLayout *layout) { GdkToplevelLayout *new_layout; new_layout = g_new0 (GdkToplevelLayout, 1); g_ref_count_init (&new_layout->ref_count); new_layout->resizable = layout->resizable; new_layout->maximized_valid = layout->maximized_valid; new_layout->maximized = layout->maximized; new_layout->fullscreen_valid = layout->fullscreen_valid; new_layout->fullscreen = layout->fullscreen; if (layout->fullscreen_monitor) new_layout->fullscreen_monitor = g_object_ref (layout->fullscreen_monitor); return new_layout; } /** * gdk_toplevel_layout_equal: * @layout: a #GdkToplevelLayout * @other: another #GdkToplevelLayout * * Check whether @layout and @other has identical layout properties. * * Returns: %TRUE if @layout and @other have identical layout properties, * otherwise %FALSE. */ gboolean gdk_toplevel_layout_equal (GdkToplevelLayout *layout, GdkToplevelLayout *other) { g_return_val_if_fail (layout, FALSE); g_return_val_if_fail (other, FALSE); return layout->resizable == other->resizable && layout->maximized_valid == other->maximized_valid && layout->maximized == other->maximized && layout->fullscreen_valid == other->fullscreen_valid && layout->fullscreen == other->fullscreen && layout->fullscreen_monitor == other->fullscreen_monitor; } /** * gdk_toplevel_layout_set_resizable: * @layout: a #GdkToplevelLayout * @resizable: %TRUE to allow resizing * * Sets whether the layout should allow the user * to resize the surface after it has been presented. */ void gdk_toplevel_layout_set_resizable (GdkToplevelLayout *layout, gboolean resizable) { layout->resizable = resizable; } /** * gdk_toplevel_layout_get_resizable: * @layout: a #GdkToplevelLayout * * Returns whether the layout should allow the user * to resize the surface. * * Returns: %TRUE if the layout is resizable */ gboolean gdk_toplevel_layout_get_resizable (GdkToplevelLayout *layout) { return layout->resizable; } /** * gdk_toplevel_layout_set_maximized: * @layout: a #GdkToplevelLayout * @maximized: %TRUE to maximize * * Sets whether the layout should cause the surface * to be maximized when presented. */ void gdk_toplevel_layout_set_maximized (GdkToplevelLayout *layout, gboolean maximized) { layout->maximized_valid = TRUE; layout->maximized = maximized; } /** * gdk_toplevel_layout_get_maximized: * @layout: a #GdkToplevelLayout * @maximized: (out): set to %TRUE if the toplevel should be maximized * * If the layout specifies whether to the toplevel should go maximized, * the value pointed to by @maximized is set to %TRUE if it should go * fullscreen, or %FALSE, if it should go unmaximized. * * Returns: whether the @layout specifies the maximized state for the toplevel */ gboolean gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout, gboolean *maximized) { if (layout->maximized_valid) { *maximized = layout->maximized; return TRUE; } return FALSE; } /** * gdk_toplevel_layout_set_fullscreen: * @layout: a #GdkToplevelLayout * @fullscreen: %TRUE to fullscreen the surface * @monitor: (nullable): the monitor to fullscreen on * * Sets whether the layout should cause the surface * to be fullscreen when presented. */ void gdk_toplevel_layout_set_fullscreen (GdkToplevelLayout *layout, gboolean fullscreen, GdkMonitor *monitor) { layout->fullscreen_valid = TRUE; layout->fullscreen = fullscreen; if (monitor) layout->fullscreen_monitor = g_object_ref (monitor); } /** * gdk_toplevel_layout_get_fullscreen: * @layout: a #GdkToplevelLayout * @fullscreen: (out): location to store whether the toplevel should be fullscreen * * If the layout specifies whether to the toplevel should go fullscreen, * the value pointed to by @fullscreen is set to %TRUE if it should go * fullscreen, or %FALSE, if it should go unfullscreen. * * Returns: whether the @layout specifies the fullscreen state for the toplevel */ gboolean gdk_toplevel_layout_get_fullscreen (GdkToplevelLayout *layout, gboolean *fullscreen) { if (layout->fullscreen_valid) { *fullscreen = layout->fullscreen; return TRUE; } return FALSE; } /** * gdk_toplevel_layout_get_fullscreen_monitor: * @layout: a #GdkToplevelLayout * * Returns the monitor that the layout is fullscreening * the surface on. * * Returns: (nullable) (transfer none): the monitor on which @layout fullscreens */ GdkMonitor * gdk_toplevel_layout_get_fullscreen_monitor (GdkToplevelLayout *layout) { return layout->fullscreen_monitor; }