forked from AuroraMiddleware/gtk
gdk/toplevel: Negotiate surface size via a compute-size signal
GTK will not up front know how to correctly calculate a size, since it will not be able to reliably predict the constraints that may exist where it will be mapped. Thus, to handle this, calculate the size of the toplevel by having GDK emitting a signal called 'compute-size' that will contain information needed for computing a toplevel window size. This signal may be emitted at any time, e.g. during gdk_toplevel_present(), or spontaneously if constraints change. This also drops the max size from the toplevel layout, while moving the min size from the toplevel layout struct to the struct passed via the signal, This needs changes to a test case where we make sure we process GDK_CONFIGURE etc, which means we also needs to show the window and process all pending events in the test-focus-chain test case.
This commit is contained in:
parent
4ee82e8175
commit
2ff74eb667
@ -633,8 +633,6 @@ gdk_toplevel_layout_get_maximized
|
||||
gdk_toplevel_layout_set_fullscreen
|
||||
gdk_toplevel_layout_get_fullscreen
|
||||
gdk_toplevel_layout_get_fullscreen_monitor
|
||||
gdk_toplevel_layout_get_min_width
|
||||
gdk_toplevel_layout_get_min_height
|
||||
gdk_toplevel_layout_set_resizable
|
||||
gdk_toplevel_layout_get_resizable
|
||||
<SUBSECTION Standard>
|
||||
@ -642,6 +640,18 @@ GDK_TYPE_TOPLEVEL_LAYOUT
|
||||
gdk_toplevel_layout_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gdktoplevelsize</FILE>
|
||||
<TITLE>GdkToplevelSize</TITLE>
|
||||
GdkToplevelSize
|
||||
gdk_toplevel_size_get_bounds
|
||||
gdk_toplevel_size_set_size
|
||||
gdk_toplevel_size_set_min_size
|
||||
<SUBSECTION Standard>
|
||||
GDK_TYPE_TOPLEVEL_SIZE
|
||||
gdk_toplevel_size_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gdktoplevel</FILE>
|
||||
<TITLE>GdkToplevel</TITLE>
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -1524,20 +1525,45 @@ show_surface (GdkSurface *surface)
|
||||
|
||||
static gboolean
|
||||
gdk_broadway_toplevel_present (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (toplevel);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
|
||||
gdk_broadway_surface_unminimize (surface);
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle monitor_geometry;
|
||||
|
||||
gdk_monitor_get_geometry (monitor, &monitor_geometry);
|
||||
bounds_width = monitor_geometry.width;
|
||||
bounds_height = monitor_geometry.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (toplevel, &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
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);
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include <gdk/gdktexture.h>
|
||||
#include <gdk/gdktoplevel.h>
|
||||
#include <gdk/gdktoplevellayout.h>
|
||||
#include <gdk/gdktoplevelsize.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
#include <gdk/gdkvulkancontext.h>
|
||||
|
@ -795,22 +795,18 @@ gdk_surface_new (GdkDisplay *display,
|
||||
/**
|
||||
* gdk_surface_new_toplevel: (constructor)
|
||||
* @display: the display to create the surface on
|
||||
* @width: width of new surface
|
||||
* @height: height of new surface
|
||||
*
|
||||
* Creates a new toplevel surface.
|
||||
*
|
||||
* Returns: (transfer full): the new #GdkSurface
|
||||
**/
|
||||
GdkSurface *
|
||||
gdk_surface_new_toplevel (GdkDisplay *display,
|
||||
int width,
|
||||
int height)
|
||||
gdk_surface_new_toplevel (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
return gdk_surface_new (display, GDK_SURFACE_TOPLEVEL,
|
||||
NULL, 0, 0, width, height);
|
||||
NULL, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,9 +139,7 @@ typedef struct _GdkSurfaceClass GdkSurfaceClass;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_surface_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_surface_new_toplevel (GdkDisplay *display,
|
||||
int width,
|
||||
int height);
|
||||
GdkSurface * gdk_surface_new_toplevel (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkSurface * gdk_surface_new_popup (GdkSurface *parent,
|
||||
gboolean autohide);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "gdk-private.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
|
||||
#include <graphene-gobject.h>
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
@ -35,10 +36,17 @@
|
||||
|
||||
G_DEFINE_INTERFACE (GdkToplevel, gdk_toplevel, GDK_TYPE_SURFACE)
|
||||
|
||||
enum
|
||||
{
|
||||
COMPUTE_SIZE,
|
||||
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
static gboolean
|
||||
gdk_toplevel_default_present (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
return FALSE;
|
||||
@ -86,6 +94,13 @@ gdk_toplevel_default_restore_system_shortcuts (GdkToplevel *toplevel)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gdk_toplevel_notify_compute_size (GdkToplevel *toplevel,
|
||||
GdkToplevelSize *size)
|
||||
{
|
||||
g_signal_emit (toplevel, signals[COMPUTE_SIZE], 0, size);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_toplevel_default_init (GdkToplevelInterface *iface)
|
||||
{
|
||||
@ -158,6 +173,37 @@ gdk_toplevel_default_init (GdkToplevelInterface *iface)
|
||||
"Whether keyboard shortcuts are inhibited",
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
/**
|
||||
* GdkToplevel::compute-size:
|
||||
* @toplevel: a #GdkToplevel
|
||||
* @size: (type Gdk.ToplevelSize) (out caller-allocates): a #GdkToplevelSize
|
||||
*
|
||||
* Compute the desired size of the toplevel, given the information passed via
|
||||
* the #GdkToplevelSize object.
|
||||
*
|
||||
* It will normally be emitted during or after gdk_toplevel_present(),
|
||||
* depending on the configuration received by the windowing system. It may
|
||||
* also be emitted at any other point in time, in response to the windowing
|
||||
* system spontaneously changing the configuration.
|
||||
*
|
||||
* It is the responsibility of the GdkToplevel user to handle this signal;
|
||||
* failing to do so will result in an arbitrary fixed size being used as a
|
||||
* result. The signal may be emitted with the pointer to the @size being
|
||||
* %NULL, in which case only the minimum and maximum size needs to be
|
||||
* computed. This could happen for example if the toplevel configuration is in
|
||||
* a state where the size is decided by the windowing system, such as
|
||||
* maximized or fullscreen.
|
||||
*/
|
||||
signals[COMPUTE_SIZE] =
|
||||
g_signal_new ("compute-size",
|
||||
GDK_TYPE_TOPLEVEL,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_TOPLEVEL_SIZE | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
}
|
||||
|
||||
guint
|
||||
@ -181,30 +227,28 @@ gdk_toplevel_install_properties (GObjectClass *object_class,
|
||||
/**
|
||||
* 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 not showing, it will be showed,
|
||||
* otherwise it will change layout according to @layout.
|
||||
*
|
||||
* GDK may emit the 'compute-size' signal to let the user of this toplevel
|
||||
* compute the preferred size of the toplevel surface. See
|
||||
* #GdkToplevel::compute-size for details.
|
||||
*
|
||||
* 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);
|
||||
return GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,8 +37,6 @@ 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
|
||||
|
@ -39,8 +39,6 @@ struct _GdkToplevelLayout
|
||||
/* < private >*/
|
||||
grefcount ref_count;
|
||||
|
||||
int min_width;
|
||||
int min_height;
|
||||
guint resizable : 1;
|
||||
guint maximized : 1;
|
||||
guint fullscreen : 1;
|
||||
@ -53,8 +51,6 @@ G_DEFINE_BOXED_TYPE (GdkToplevelLayout, gdk_toplevel_layout,
|
||||
|
||||
/**
|
||||
* gdk_toplevel_layout_new: (constructor)
|
||||
* @min_width: the minimum width for the layout
|
||||
* @min_height: the minimum height for the layout
|
||||
*
|
||||
* Create a toplevel layout description.
|
||||
*
|
||||
@ -67,15 +63,12 @@ G_DEFINE_BOXED_TYPE (GdkToplevelLayout, gdk_toplevel_layout,
|
||||
* Returns: (transfer full): newly created instance of #GdkToplevelLayout
|
||||
*/
|
||||
GdkToplevelLayout *
|
||||
gdk_toplevel_layout_new (int min_width,
|
||||
int min_height)
|
||||
gdk_toplevel_layout_new (void)
|
||||
{
|
||||
GdkToplevelLayout *layout;
|
||||
|
||||
layout = g_new0 (GdkToplevelLayout, 1);
|
||||
g_ref_count_init (&layout->ref_count);
|
||||
layout->min_width = min_width;
|
||||
layout->min_height = min_height;
|
||||
layout->resizable = TRUE;
|
||||
layout->maximized = FALSE;
|
||||
layout->fullscreen = FALSE;
|
||||
@ -131,8 +124,6 @@ gdk_toplevel_layout_copy (GdkToplevelLayout *layout)
|
||||
new_layout = g_new0 (GdkToplevelLayout, 1);
|
||||
g_ref_count_init (&new_layout->ref_count);
|
||||
|
||||
new_layout->min_width = layout->min_width;
|
||||
new_layout->min_height = layout->min_height;
|
||||
new_layout->resizable = layout->resizable;
|
||||
new_layout->maximized = layout->maximized;
|
||||
new_layout->fullscreen = layout->fullscreen;
|
||||
@ -159,42 +150,12 @@ gdk_toplevel_layout_equal (GdkToplevelLayout *layout,
|
||||
g_return_val_if_fail (layout, FALSE);
|
||||
g_return_val_if_fail (other, FALSE);
|
||||
|
||||
return layout->min_width == other->min_width &&
|
||||
layout->min_height == other->min_height &&
|
||||
layout->resizable == other->resizable &&
|
||||
return layout->resizable == other->resizable &&
|
||||
layout->maximized == other->maximized &&
|
||||
layout->fullscreen == other->fullscreen &&
|
||||
layout->fullscreen_monitor == other->fullscreen_monitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_toplevel_layout_get_min_width:
|
||||
* @layout: a #GdkToplevelLayout
|
||||
*
|
||||
* Returns the minimum width of the given layout.
|
||||
*
|
||||
* Returns: the minimum width of @layout
|
||||
*/
|
||||
int
|
||||
gdk_toplevel_layout_get_min_width (GdkToplevelLayout *layout)
|
||||
{
|
||||
return layout->min_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_toplevel_layout_get_min_height:
|
||||
* @layout: a #GdkToplevelLayout
|
||||
*
|
||||
* Returns the minimum height of the given layout.
|
||||
*
|
||||
* Returns: the minimum height of @layout
|
||||
*/
|
||||
int
|
||||
gdk_toplevel_layout_get_min_height (GdkToplevelLayout *layout)
|
||||
{
|
||||
return layout->min_height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_toplevel_layout_set_resizable:
|
||||
* @layout: a #GdkToplevelLayout
|
||||
|
@ -42,8 +42,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_toplevel_layout_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkToplevelLayout * gdk_toplevel_layout_new (int min_width,
|
||||
int min_height);
|
||||
GdkToplevelLayout * gdk_toplevel_layout_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkToplevelLayout * gdk_toplevel_layout_ref (GdkToplevelLayout *layout);
|
||||
@ -66,11 +65,6 @@ void gdk_toplevel_layout_set_fullscreen (GdkToplevelLayout *l
|
||||
gboolean fullscreen,
|
||||
GdkMonitor *monitor);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_toplevel_layout_get_min_width (GdkToplevelLayout *layout);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_toplevel_layout_get_min_height (GdkToplevelLayout *layout);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_toplevel_layout_get_maximized (GdkToplevelLayout *layout);
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
#define __GDK_TOPLEVEL_PRIVATE_H__
|
||||
|
||||
#include "gdktoplevel.h"
|
||||
#include "gdktoplevelsizeprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -11,8 +14,6 @@ struct _GdkToplevelInterface
|
||||
GTypeInterface g_iface;
|
||||
|
||||
gboolean (* present) (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout);
|
||||
gboolean (* minimize) (GdkToplevel *toplevel);
|
||||
gboolean (* lower) (GdkToplevel *toplevel);
|
||||
@ -57,6 +58,9 @@ typedef enum
|
||||
guint gdk_toplevel_install_properties (GObjectClass *object_class,
|
||||
guint first_prop);
|
||||
|
||||
void gdk_toplevel_notify_compute_size (GdkToplevel *toplevel,
|
||||
GdkToplevelSize *size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_TOPLEVEL_PRIVATE_H__ */
|
||||
|
119
gdk/gdktoplevelsize.c
Normal file
119
gdk/gdktoplevelsize.c
Normal file
@ -0,0 +1,119 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdktoplevelsizeprivate.h"
|
||||
|
||||
/**
|
||||
* SECTION:gdktoplevelsize
|
||||
* @Title: GdkToplevelSize
|
||||
* @Short_description: Information for computing toplevel size
|
||||
*
|
||||
* The GdkToplevelSIze struct contains information that may be useful
|
||||
* for users of GdkToplevel to compute a surface size. It also carries
|
||||
* information back with the computational result.
|
||||
*/
|
||||
|
||||
G_DEFINE_POINTER_TYPE (GdkToplevelSize, gdk_toplevel_size)
|
||||
|
||||
#define UNCONFIGURED_WIDTH 400
|
||||
#define UNCONFIGURED_HEIGHT 300
|
||||
|
||||
void
|
||||
gdk_toplevel_size_init (GdkToplevelSize *size,
|
||||
int bounds_width,
|
||||
int bounds_height)
|
||||
{
|
||||
*size = (GdkToplevelSize) { 0 };
|
||||
|
||||
size->bounds_width = bounds_width;
|
||||
size->bounds_height = bounds_height;
|
||||
|
||||
size->width = UNCONFIGURED_WIDTH;
|
||||
size->height = UNCONFIGURED_HEIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_toplevel_size_get_bounds:
|
||||
* @size: a #GdkToplevelSize
|
||||
* @bounds_width: (out): return location for width
|
||||
* @bounds_height: (out): return location for height
|
||||
*
|
||||
* Retrieves the bounds the toplevel is placed within.
|
||||
*
|
||||
* The bounds represent the largest size a toplevel may have while still being
|
||||
* able to fit within some type of boundery. Depending on the backend, this may
|
||||
* be equivalent to the dimensions of the work area or the monitor on which the
|
||||
* window is being presented on, or something else that limits the way a
|
||||
* toplevel can be presented.
|
||||
*/
|
||||
void
|
||||
gdk_toplevel_size_get_bounds (GdkToplevelSize *size,
|
||||
int *bounds_width,
|
||||
int *bounds_height)
|
||||
{
|
||||
g_return_if_fail (bounds_width);
|
||||
g_return_if_fail (bounds_height);
|
||||
|
||||
*bounds_width = size->bounds_width;
|
||||
*bounds_height = size->bounds_height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_toplevel_size_set_size:
|
||||
* @size: a #GdkToplevelSize
|
||||
* @width: the width
|
||||
* @height: the height
|
||||
*
|
||||
* Sets the size the toplevel prefers to be resized to. The size should be
|
||||
* within the bounds (see gdk_toplevel_size_get_bounds()). The set size should
|
||||
* be considered as a hint, and should not be assumed to be respected by the
|
||||
* windowing system, or backend.
|
||||
*/
|
||||
void
|
||||
gdk_toplevel_size_set_size (GdkToplevelSize *size,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
size->width = width;
|
||||
size->height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_toplevel_size_set_min_size:
|
||||
* @size: a #GdkToplevelSize
|
||||
* @min_width: the minimum width
|
||||
* @min_height: the minimum height
|
||||
*
|
||||
* The minimum size corresponds to the limitations the toplevel can be shrunk
|
||||
* to, without resulting in incorrect painting. A user of a #GdkToplevel should
|
||||
* calculate these given both the existing size, and the bounds retrieved from
|
||||
* the #GdkToplevelSize object.
|
||||
*
|
||||
* The minimum size should be within the bounds (see
|
||||
* gdk_toplevel_size_get_bounds()).
|
||||
*/
|
||||
void
|
||||
gdk_toplevel_size_set_min_size (GdkToplevelSize *size,
|
||||
int min_width,
|
||||
int min_height)
|
||||
{
|
||||
size->min_width = min_width;
|
||||
size->min_height = min_height;
|
||||
}
|
62
gdk/gdktoplevelsize.h
Normal file
62
gdk/gdktoplevelsize.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GDK_TOPLEVEL_SIZE_H__
|
||||
#define __GDK_TOPLEVEL_SIZE_H__
|
||||
|
||||
#if !defined(__GDK_H_INSIDE__) && !defined(GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GdkTopLevelSize:
|
||||
*
|
||||
* Struct containing information for computing the size of a #GdkToplevel.
|
||||
*/
|
||||
typedef struct _GdkToplevelSize GdkToplevelSize;
|
||||
|
||||
#define GDK_TYPE_TOPLEVEL_SIZE (gdk_toplevel_size_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_toplevel_size_get_type (void);
|
||||
|
||||
void gdk_toplevel_size_get_bounds (GdkToplevelSize *size,
|
||||
int *bounds_width,
|
||||
int *bounds_height);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_toplevel_size_set_size (GdkToplevelSize *size,
|
||||
int width,
|
||||
int height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_toplevel_size_set_min_size (GdkToplevelSize *size,
|
||||
int min_width,
|
||||
int min_height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_toplevel_size_set_max_size (GdkToplevelSize *size,
|
||||
int max_width,
|
||||
int max_height);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_TOPLEVEL_SIZE_H__ */
|
39
gdk/gdktoplevelsizeprivate.h
Normal file
39
gdk/gdktoplevelsizeprivate.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GDK_TOPLEVEL_SIZE_PRIVATE_H__
|
||||
#define __GDK_TOPLEVEL_SIZE_PRIVATE_H__
|
||||
|
||||
#include "gdktoplevelsize.h"
|
||||
|
||||
struct _GdkToplevelSize
|
||||
{
|
||||
int bounds_width;
|
||||
int bounds_height;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int min_width;
|
||||
int min_height;
|
||||
};
|
||||
|
||||
void gdk_toplevel_size_init (GdkToplevelSize *size,
|
||||
int bounds_width,
|
||||
int bounds_height);
|
||||
|
||||
#endif /* __GDK_TOPLEVEL_SIZE_PRIVATE_H__ */
|
@ -93,12 +93,15 @@ _gdk_macos_toplevel_surface_unmaximize (GdkMacosToplevelSurface *self)
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
|
||||
NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
NSWindowStyleMask style_mask;
|
||||
@ -108,10 +111,32 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_macos_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (toplevel, &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
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);
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
|
||||
/* Only set 'Resizable' mask to get native resize zones if the window is
|
||||
|
@ -47,6 +47,7 @@ gdk_public_sources = files([
|
||||
'gdkprofiler.c',
|
||||
'gdkpopup.c',
|
||||
'gdktoplevellayout.c',
|
||||
'gdktoplevelsize.c',
|
||||
'gdktoplevel.c',
|
||||
'gdkdragsurface.c',
|
||||
])
|
||||
@ -95,6 +96,7 @@ gdk_public_headers = files([
|
||||
'gdkpopuplayout.h',
|
||||
'gdkpopup.h',
|
||||
'gdktoplevellayout.h',
|
||||
'gdktoplevelsize.h',
|
||||
'gdktoplevel.h',
|
||||
'gdkdragsurface.h',
|
||||
])
|
||||
@ -107,6 +109,7 @@ gdk_private_h_sources = files([
|
||||
'gdkdevicetoolprivate.h',
|
||||
'gdkmonitorprivate.h',
|
||||
'gdkseatdefaultprivate.h',
|
||||
'gdktoplevelsizeprivate.h',
|
||||
])
|
||||
|
||||
gdk_gresource_xml = configure_file(output : 'gdk.gresource.xml',
|
||||
|
@ -146,11 +146,21 @@ struct _GdkWaylandSurface
|
||||
cairo_region_t *input_region;
|
||||
gboolean input_region_dirty;
|
||||
|
||||
GdkRectangle last_sent_window_geometry;
|
||||
int last_sent_min_width;
|
||||
int last_sent_min_height;
|
||||
int last_sent_max_width;
|
||||
int last_sent_max_height;
|
||||
|
||||
int saved_width;
|
||||
int saved_height;
|
||||
|
||||
gulong parent_surface_committed_handler;
|
||||
|
||||
struct {
|
||||
GdkToplevelLayout *layout;
|
||||
} toplevel;
|
||||
|
||||
struct {
|
||||
GdkPopupLayout *layout;
|
||||
int unconstrained_width;
|
||||
@ -1112,6 +1122,9 @@ gdk_wayland_surface_sync_margin (GdkSurface *surface)
|
||||
&impl->geometry_hints,
|
||||
impl->geometry_mask);
|
||||
|
||||
if (gdk_rectangle_equal (&geometry, &impl->last_sent_window_geometry))
|
||||
return;
|
||||
|
||||
switch (display_wayland->shell_variant)
|
||||
{
|
||||
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
|
||||
@ -1131,6 +1144,8 @@ gdk_wayland_surface_sync_margin (GdkSurface *surface)
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
impl->last_sent_window_geometry = geometry;
|
||||
}
|
||||
|
||||
static struct wl_region *
|
||||
@ -1265,6 +1280,50 @@ gdk_wayland_surface_create_surface (GdkSurface *surface)
|
||||
impl->display_server.wl_surface = wl_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
configure_surface_geometry (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle monitor_geometry;
|
||||
int bounds_width, bounds_height;
|
||||
GdkToplevelSize size;
|
||||
int width, height;
|
||||
GdkToplevelLayout *layout;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
|
||||
monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
|
||||
gdk_monitor_get_geometry (monitor, &monitor_geometry);
|
||||
bounds_width = monitor_geometry.width;
|
||||
bounds_height = monitor_geometry.height;
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
g_warn_if_fail (width > 0);
|
||||
g_warn_if_fail (height > 0);
|
||||
|
||||
layout = impl->toplevel.layout;
|
||||
if (gdk_toplevel_layout_get_resizable (layout))
|
||||
{
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
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_wayland_surface_set_geometry_hints (surface, &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
gdk_wayland_surface_resize (surface, width, height, impl->scale);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
|
||||
{
|
||||
@ -1322,6 +1381,10 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
|
||||
|
||||
gdk_wayland_surface_resize (surface, width, height, impl->scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
configure_surface_geometry (surface);
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS,
|
||||
g_message ("configure, surface %p %dx%d,%s%s%s%s",
|
||||
@ -2729,6 +2792,7 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
g_slist_free (impl->display_server.outputs);
|
||||
impl->display_server.outputs = NULL;
|
||||
|
||||
g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref);
|
||||
g_clear_pointer (&impl->popup.layout, gdk_popup_layout_unref);
|
||||
}
|
||||
|
||||
@ -3369,6 +3433,12 @@ gdk_wayland_surface_set_geometry_hints (GdkSurface *surface,
|
||||
max_height = 0;
|
||||
}
|
||||
|
||||
if (impl->last_sent_min_width == min_width &&
|
||||
impl->last_sent_min_height == min_height &&
|
||||
impl->last_sent_max_width == max_width &&
|
||||
impl->last_sent_max_height == max_height)
|
||||
return;
|
||||
|
||||
switch (display_wayland->shell_variant)
|
||||
{
|
||||
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
|
||||
@ -3386,6 +3456,11 @@ gdk_wayland_surface_set_geometry_hints (GdkSurface *surface,
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
impl->last_sent_min_width = min_width;
|
||||
impl->last_sent_min_height = min_height;
|
||||
impl->last_sent_max_width = max_width;
|
||||
impl->last_sent_max_height = max_height;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4676,37 +4751,41 @@ show_surface (GdkSurface *surface)
|
||||
gdk_surface_invalidate_rect (surface, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
reconfigure_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
gboolean *done = (gboolean *) data;
|
||||
|
||||
*done = TRUE;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener reconfigure_listener = {
|
||||
reconfigure_callback
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_toplevel_present (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (toplevel);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
|
||||
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_wayland_surface_set_geometry_hints (surface, &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
gdk_wayland_surface_resize (surface, width, height, impl->scale);
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
struct wl_callback *callback;
|
||||
gboolean done = FALSE;
|
||||
int last_configure_serial = impl->last_configure_serial;
|
||||
gboolean needs_reconfigure = TRUE;
|
||||
|
||||
if (gdk_toplevel_layout_get_maximized (layout))
|
||||
gdk_wayland_surface_maximize (surface);
|
||||
{
|
||||
gdk_wayland_surface_maximize (surface);
|
||||
needs_reconfigure = FALSE;
|
||||
}
|
||||
else
|
||||
gdk_wayland_surface_unmaximize (surface);
|
||||
{
|
||||
gdk_wayland_surface_unmaximize (surface);
|
||||
}
|
||||
|
||||
if (gdk_toplevel_layout_get_fullscreen (layout))
|
||||
{
|
||||
@ -4715,12 +4794,34 @@ gdk_wayland_toplevel_present (GdkToplevel *toplevel,
|
||||
gdk_wayland_surface_fullscreen_on_monitor (surface, monitor);
|
||||
else
|
||||
gdk_wayland_surface_fullscreen (surface);
|
||||
needs_reconfigure = FALSE;
|
||||
}
|
||||
else
|
||||
gdk_wayland_surface_unfullscreen (surface);
|
||||
|
||||
g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref);
|
||||
impl->toplevel.layout = gdk_toplevel_layout_copy (layout);
|
||||
|
||||
show_surface (surface);
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
callback = wl_display_sync (display_wayland->wl_display);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) callback, impl->event_queue);
|
||||
wl_callback_add_listener (callback,
|
||||
&reconfigure_listener,
|
||||
&done);
|
||||
while (is_realized_toplevel (surface) &&
|
||||
!impl->initial_configure_received &&
|
||||
!done)
|
||||
wl_display_dispatch_queue (display_wayland->wl_display, impl->event_queue);
|
||||
|
||||
if (needs_reconfigure &&
|
||||
last_configure_serial == impl->last_configure_serial &&
|
||||
!(surface->state & (GDK_SURFACE_STATE_MAXIMIZED |
|
||||
GDK_SURFACE_STATE_FULLSCREEN |
|
||||
GDK_SURFACE_STATE_TILED)))
|
||||
configure_surface_geometry (surface);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -4941,18 +4941,43 @@ show_surface (GdkSurface *surface)
|
||||
|
||||
static gboolean
|
||||
gdk_win32_toplevel_present (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout)
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (toplevel);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_win32_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (toplevel, &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
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);
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdk-private.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -1017,7 +1018,8 @@ _gdk_x11_display_create_surface (GdkDisplay *display,
|
||||
impl->xid = XCreateWindow (xdisplay, xparent,
|
||||
(surface->x + abs_x) * impl->surface_scale,
|
||||
(surface->y + abs_y) * impl->surface_scale,
|
||||
surface->width * impl->surface_scale, surface->height * impl->surface_scale,
|
||||
MAX (1, surface->width * impl->surface_scale),
|
||||
MAX (1, surface->height * impl->surface_scale),
|
||||
0, depth, class, xvisual,
|
||||
xattributes_mask, &xattributes);
|
||||
|
||||
@ -4830,21 +4832,46 @@ gdk_x11_toplevel_class_init (GdkX11ToplevelClass *class)
|
||||
|
||||
static gboolean
|
||||
gdk_x11_toplevel_present (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (toplevel);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkMonitor *monitor;
|
||||
GdkToplevelSize size;
|
||||
int bounds_width, bounds_height;
|
||||
int width, height;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
gboolean was_mapped;
|
||||
|
||||
gdk_x11_surface_unminimize (surface);
|
||||
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
{
|
||||
GdkRectangle workarea;
|
||||
|
||||
gdk_x11_monitor_get_workarea (monitor, &workarea);
|
||||
bounds_width = workarea.width;
|
||||
bounds_height = workarea.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds_width = G_MAXINT;
|
||||
bounds_height = G_MAXINT;
|
||||
}
|
||||
|
||||
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
|
||||
gdk_toplevel_notify_compute_size (toplevel, &size);
|
||||
g_warn_if_fail (size.width > 0);
|
||||
g_warn_if_fail (size.height > 0);
|
||||
width = size.width;
|
||||
height = size.height;
|
||||
|
||||
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);
|
||||
geometry.min_width = size.min_width;
|
||||
geometry.min_height = size.min_height;
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
}
|
||||
else
|
||||
@ -4864,9 +4891,11 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
|
||||
|
||||
if (gdk_toplevel_layout_get_fullscreen (layout))
|
||||
{
|
||||
GdkMonitor *monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
|
||||
if (monitor)
|
||||
gdk_x11_surface_fullscreen_on_monitor (surface, monitor);
|
||||
GdkMonitor *fullscreen_monitor =
|
||||
gdk_toplevel_layout_get_fullscreen_monitor (layout);
|
||||
|
||||
if (fullscreen_monitor)
|
||||
gdk_x11_surface_fullscreen_on_monitor (surface, fullscreen_monitor);
|
||||
else
|
||||
gdk_x11_surface_fullscreen (surface);
|
||||
}
|
||||
|
244
gtk/gtkwindow.c
244
gtk/gtkwindow.c
@ -471,9 +471,7 @@ static void _gtk_window_set_is_active (GtkWindow *window,
|
||||
gboolean is_active);
|
||||
static void gtk_window_present_toplevel (GtkWindow *window);
|
||||
static void gtk_window_update_toplevel (GtkWindow *window);
|
||||
static GdkToplevelLayout * gtk_window_compute_layout (GtkWindow *window,
|
||||
int min_width,
|
||||
int min_height);
|
||||
static GdkToplevelLayout * gtk_window_compute_layout (GtkWindow *window);
|
||||
|
||||
static void gtk_window_release_application (GtkWindow *window);
|
||||
|
||||
@ -3839,14 +3837,12 @@ gtk_window_hide (GtkWidget *widget)
|
||||
}
|
||||
|
||||
static GdkToplevelLayout *
|
||||
gtk_window_compute_layout (GtkWindow *window,
|
||||
int min_width,
|
||||
int min_height)
|
||||
gtk_window_compute_layout (GtkWindow *window)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
GdkToplevelLayout *layout;
|
||||
|
||||
layout = gdk_toplevel_layout_new (min_width, min_height);
|
||||
layout = gdk_toplevel_layout_new ();
|
||||
|
||||
gdk_toplevel_layout_set_resizable (layout, priv->resizable);
|
||||
gdk_toplevel_layout_set_maximized (layout, priv->maximize_initially);
|
||||
@ -3861,23 +3857,11 @@ static void
|
||||
gtk_window_present_toplevel (GtkWindow *window)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
GdkRectangle request;
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints flags;
|
||||
|
||||
gtk_window_compute_configure_request (window, &request,
|
||||
&geometry, &flags);
|
||||
|
||||
if (!(flags & GDK_HINT_MIN_SIZE))
|
||||
geometry.min_width = geometry.min_height = 1;
|
||||
|
||||
if (!priv->layout)
|
||||
priv->layout = gtk_window_compute_layout (window, geometry.min_width, geometry.min_height);
|
||||
priv->layout = gtk_window_compute_layout (window);
|
||||
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (priv->surface),
|
||||
request.width,
|
||||
request.height,
|
||||
priv->layout);
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (priv->surface), priv->layout);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3887,22 +3871,10 @@ gtk_window_update_toplevel (GtkWindow *window)
|
||||
|
||||
if (priv->surface && gdk_surface_get_mapped (priv->surface))
|
||||
{
|
||||
int min_width = 1;
|
||||
int min_height = 1;
|
||||
|
||||
if (priv->layout)
|
||||
{
|
||||
min_width = gdk_toplevel_layout_get_min_width (priv->layout);
|
||||
min_height = gdk_toplevel_layout_get_min_height (priv->layout);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->layout, gdk_toplevel_layout_unref);
|
||||
priv->layout = gtk_window_compute_layout (window, min_width, min_height);
|
||||
priv->layout = gtk_window_compute_layout (window);
|
||||
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (priv->surface),
|
||||
gdk_surface_get_width (priv->surface),
|
||||
gdk_surface_get_height (priv->surface),
|
||||
priv->layout);
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (priv->surface), priv->layout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3930,9 +3902,6 @@ gtk_window_map (GtkWidget *widget)
|
||||
|
||||
gtk_window_set_theme_variant (window);
|
||||
|
||||
/* No longer use the default settings */
|
||||
priv->need_default_size = FALSE;
|
||||
|
||||
if (!disable_startup_notification)
|
||||
{
|
||||
/* Do we have a custom startup-notification id? */
|
||||
@ -4014,7 +3983,7 @@ gtk_window_guess_default_size (GtkWindow *window,
|
||||
GtkWidget *widget;
|
||||
GdkSurface *surface;
|
||||
GdkDisplay *display;
|
||||
GdkMonitor *monitor;
|
||||
GdkMonitor *monitor = NULL;
|
||||
GdkRectangle geometry;
|
||||
int minimum, natural;
|
||||
|
||||
@ -4025,21 +3994,22 @@ gtk_window_guess_default_size (GtkWindow *window,
|
||||
if (surface)
|
||||
{
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
if (monitor)
|
||||
g_object_ref (monitor);
|
||||
}
|
||||
|
||||
if (!monitor)
|
||||
monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
|
||||
|
||||
if (monitor)
|
||||
{
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
g_object_unref (monitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
|
||||
if (monitor)
|
||||
{
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
g_object_unref (monitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.width = G_MAXINT;
|
||||
geometry.height = G_MAXINT;
|
||||
}
|
||||
geometry.width = G_MAXINT;
|
||||
geometry.height = G_MAXINT;
|
||||
}
|
||||
|
||||
*width = geometry.width;
|
||||
@ -4277,14 +4247,150 @@ update_realized_window_properties (GtkWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_compute_default_size (GtkWindow *window,
|
||||
int max_width,
|
||||
int max_height,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
GtkWidget *widget = GTK_WIDGET (window);
|
||||
|
||||
*width = max_width;
|
||||
*height = max_height;
|
||||
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
|
||||
{
|
||||
int minimum, natural;
|
||||
|
||||
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1,
|
||||
&minimum, &natural,
|
||||
NULL, NULL);
|
||||
*height = MAX (minimum, MIN (*height, natural));
|
||||
|
||||
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL,
|
||||
*height,
|
||||
&minimum, &natural,
|
||||
NULL, NULL);
|
||||
*width = MAX (minimum, MIN (*width, natural));
|
||||
}
|
||||
else /* GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH or CONSTANT_SIZE */
|
||||
{
|
||||
int minimum, natural;
|
||||
|
||||
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
&minimum, &natural,
|
||||
NULL, NULL);
|
||||
*width = MAX (minimum, MIN (*width, natural));
|
||||
|
||||
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL,
|
||||
*width,
|
||||
&minimum, &natural,
|
||||
NULL, NULL);
|
||||
*height = MAX (minimum, MIN (*height, natural));
|
||||
}
|
||||
|
||||
/* No longer use the default settings */
|
||||
priv->need_default_size = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_compute_size (GdkToplevel *toplevel,
|
||||
GdkToplevelSize *size,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
GtkWindowGeometryInfo *info;
|
||||
int width, height;
|
||||
GtkBorder shadow;
|
||||
int min_width, min_height;
|
||||
|
||||
info = gtk_window_get_geometry_info (window, FALSE);
|
||||
|
||||
if (priv->need_default_size)
|
||||
{
|
||||
int remembered_width;
|
||||
int remembered_height;
|
||||
int bounds_width;
|
||||
int bounds_height;
|
||||
|
||||
gdk_toplevel_size_get_bounds (size, &bounds_width, &bounds_height);
|
||||
|
||||
gtk_window_compute_default_size (window,
|
||||
bounds_width, bounds_height,
|
||||
&width, &height);
|
||||
gtk_window_get_remembered_size (window,
|
||||
&remembered_width, &remembered_height);
|
||||
width = MAX (width, remembered_width);
|
||||
height = MAX (height, remembered_height);
|
||||
|
||||
/* Override with default size */
|
||||
if (info)
|
||||
{
|
||||
/* Take width of shadows/headerbar into account. We want to set the
|
||||
* default size of the content area and not the window area.
|
||||
*/
|
||||
int default_width_csd = info->default_width;
|
||||
int default_height_csd = info->default_height;
|
||||
gtk_window_update_csd_size (window,
|
||||
&default_width_csd, &default_height_csd,
|
||||
INCLUDE_CSD_SIZE);
|
||||
|
||||
if (info->default_width > 0)
|
||||
width = default_width_csd;
|
||||
if (info->default_height > 0)
|
||||
height = default_height_csd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Default to keeping current size */
|
||||
gtk_window_get_remembered_size (window, &width, &height);
|
||||
}
|
||||
|
||||
/* Override any size with gtk_window_resize() values */
|
||||
if (priv->maximized || priv->fullscreen)
|
||||
{
|
||||
/* Unless we are maximized or fullscreen */
|
||||
gtk_window_get_remembered_size (window, &width, &height);
|
||||
}
|
||||
else if (info)
|
||||
{
|
||||
int resize_width_csd = info->resize_width;
|
||||
int resize_height_csd = info->resize_height;
|
||||
gtk_window_update_csd_size (window,
|
||||
&resize_width_csd, &resize_height_csd,
|
||||
INCLUDE_CSD_SIZE);
|
||||
|
||||
if (info->resize_width > 0)
|
||||
width = resize_width_csd;
|
||||
if (info->resize_height > 0)
|
||||
height = resize_height_csd;
|
||||
}
|
||||
|
||||
/* Don't ever request zero width or height, it's not supported by
|
||||
gdk. The size allocation code will round it to 1 anyway but if
|
||||
we do it then the value returned from this function will is
|
||||
not comparable to the size allocation read from the GtkWindow. */
|
||||
width = MAX (width, 1);
|
||||
height = MAX (height, 1);
|
||||
|
||||
gdk_toplevel_size_set_size (size, width, height);
|
||||
|
||||
get_shadow_width (window, &shadow);
|
||||
|
||||
min_width = width + shadow.left + shadow.right;
|
||||
min_height = height + shadow.top + shadow.bottom;
|
||||
gdk_toplevel_size_set_min_size (size, min_width, min_height);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_realize (GtkWidget *widget)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
|
||||
GtkAllocation allocation;
|
||||
GdkSurface *surface;
|
||||
GtkBorder shadow;
|
||||
|
||||
/* Create default title bar */
|
||||
if (!priv->client_decorated && gtk_window_should_use_csd (window))
|
||||
@ -4308,32 +4414,7 @@ gtk_window_realize (GtkWidget *widget)
|
||||
}
|
||||
}
|
||||
|
||||
get_shadow_width (window, &shadow);
|
||||
|
||||
/* ensure widget tree is properly size allocated */
|
||||
if (_gtk_widget_get_alloc_needed (widget))
|
||||
{
|
||||
GdkRectangle request;
|
||||
|
||||
gtk_window_compute_configure_request (window, &request, NULL, NULL);
|
||||
|
||||
allocation.x = shadow.left;
|
||||
allocation.y = shadow.top;
|
||||
allocation.width = request.width - shadow.left - shadow.right;
|
||||
allocation.height = request.height - shadow.top - shadow.bottom;
|
||||
|
||||
gtk_widget_size_allocate (widget, &allocation, -1);
|
||||
|
||||
gtk_widget_queue_resize (widget);
|
||||
|
||||
g_return_if_fail (!_gtk_widget_get_realized (widget));
|
||||
}
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
surface = gdk_surface_new_toplevel (gtk_widget_get_display (widget),
|
||||
MAX (1, allocation.width + shadow.left + shadow.right),
|
||||
MAX (1, allocation.height + shadow.top + shadow.bottom));
|
||||
surface = gdk_surface_new_toplevel (gtk_widget_get_display (widget));
|
||||
priv->surface = surface;
|
||||
gdk_surface_set_widget (surface, widget);
|
||||
|
||||
@ -4341,6 +4422,7 @@ gtk_window_realize (GtkWidget *widget)
|
||||
g_signal_connect_swapped (surface, "size-changed", G_CALLBACK (surface_size_changed), widget);
|
||||
g_signal_connect (surface, "render", G_CALLBACK (surface_render), widget);
|
||||
g_signal_connect (surface, "event", G_CALLBACK (surface_event), widget);
|
||||
g_signal_connect (surface, "compute-size", G_CALLBACK (toplevel_compute_size), widget);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_window_parent_class)->realize (widget);
|
||||
|
||||
@ -5376,7 +5458,7 @@ gtk_window_move_resize (GtkWindow *window)
|
||||
new_geometry.min_width = new_geometry.min_height = 1;
|
||||
|
||||
g_clear_pointer (&priv->layout, gdk_toplevel_layout_unref);
|
||||
priv->layout = gtk_window_compute_layout (window, new_geometry.min_width, new_geometry.min_height);
|
||||
priv->layout = gtk_window_compute_layout (window);
|
||||
|
||||
/* This check implies the invariant that we never set info->last
|
||||
* without setting the hints and sending off a configure request.
|
||||
@ -5573,9 +5655,7 @@ gtk_window_move_resize (GtkWindow *window)
|
||||
if (configure_request_pos_changed)
|
||||
g_warning ("configure request position changed. This should not happen. Ignoring the position");
|
||||
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (priv->surface),
|
||||
new_request.width, new_request.height,
|
||||
priv->layout);
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (priv->surface), priv->layout);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -141,7 +141,7 @@ init_version (GtkInspectorGeneral *gen)
|
||||
#endif
|
||||
backend = "Unknown";
|
||||
|
||||
surface = gdk_surface_new_toplevel (gen->display, 10, 10);
|
||||
surface = gdk_surface_new_toplevel (gen->display);
|
||||
gsk_renderer = gsk_renderer_new_for_surface (surface);
|
||||
if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskVulkanRenderer") == 0)
|
||||
renderer = "Vulkan";
|
||||
@ -402,7 +402,7 @@ init_vulkan (GtkInspectorGeneral *gen)
|
||||
GdkSurface *surface;
|
||||
GdkVulkanContext *context;
|
||||
|
||||
surface = gdk_surface_new_toplevel (gen->display, 10, 10);
|
||||
surface = gdk_surface_new_toplevel (gen->display);
|
||||
context = gdk_surface_create_vulkan_context (surface, NULL);
|
||||
gdk_surface_destroy (surface);
|
||||
|
||||
|
@ -128,7 +128,7 @@ main(int argc, char **argv)
|
||||
GdkSurface *window;
|
||||
GdkTexture *texture = NULL;
|
||||
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default(), 10 , 10);
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||
renderer = gsk_renderer_new_for_surface (window);
|
||||
|
||||
for (run = 0; run < runs; run++)
|
||||
|
@ -181,7 +181,7 @@ main (int argc, char **argv)
|
||||
|
||||
if (write_to_filename != NULL)
|
||||
{
|
||||
GdkSurface *surface = gdk_surface_new_toplevel (gdk_display_get_default(), 10 , 10);
|
||||
GdkSurface *surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||
GskRenderer *renderer = gsk_renderer_new_for_surface (surface);
|
||||
GdkTexture *texture = gsk_renderer_render_texture (renderer, GTK_NODE_VIEW (nodeview)->node, NULL);
|
||||
|
||||
@ -201,7 +201,7 @@ main (int argc, char **argv)
|
||||
if (compare_node)
|
||||
{
|
||||
GtkWidget *box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
GdkSurface *gdk_surface = gdk_surface_new_toplevel (gdk_display_get_default(), 10 , 10);
|
||||
GdkSurface *gdk_surface = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||
GskRenderer *renderer = gsk_renderer_new_for_surface (gdk_surface);
|
||||
GdkTexture *texture = gsk_renderer_render_texture (renderer, GTK_NODE_VIEW (nodeview)->node, NULL);
|
||||
GtkWidget *image = gtk_image_new_from_paintable (GDK_PAINTABLE (texture));
|
||||
|
@ -34,13 +34,10 @@ set_fullscreen_monitor_cb (GtkWidget *widget, gpointer user_data)
|
||||
monitor = gdk_display_get_monitor_at_surface (display, surface);
|
||||
else
|
||||
monitor = NULL;
|
||||
layout = gdk_toplevel_layout_new (0, 0);
|
||||
layout = gdk_toplevel_layout_new ();
|
||||
gdk_toplevel_layout_set_resizable (layout, TRUE);
|
||||
gdk_toplevel_layout_set_fullscreen (layout, TRUE, monitor);
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (surface),
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface),
|
||||
layout);
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (surface), layout);
|
||||
gdk_toplevel_layout_unref (layout);
|
||||
}
|
||||
|
||||
@ -51,13 +48,10 @@ remove_fullscreen_cb (GtkWidget *widget, gpointer user_data)
|
||||
GdkToplevelLayout *layout;
|
||||
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (widget));
|
||||
layout = gdk_toplevel_layout_new (0, 0);
|
||||
layout = gdk_toplevel_layout_new ();
|
||||
gdk_toplevel_layout_set_resizable (layout, TRUE);
|
||||
gdk_toplevel_layout_set_fullscreen (layout, FALSE, NULL);
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (surface),
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface),
|
||||
layout);
|
||||
gdk_toplevel_present (GDK_TOPLEVEL (surface), layout);
|
||||
gdk_toplevel_layout_unref (layout);
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ main (int argc, char **argv)
|
||||
node_file = argv[1];
|
||||
png_file = argv[2];
|
||||
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default(), 10 , 10);
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default());
|
||||
renderer = gsk_renderer_new_for_surface (window);
|
||||
|
||||
g_print ("Node file: '%s'\n", node_file);
|
||||
|
@ -110,7 +110,7 @@ test_type (gconstpointer data)
|
||||
instance = G_OBJECT (g_object_ref (gtk_settings_get_default ()));
|
||||
else if (g_type_is_a (type, GDK_TYPE_SURFACE))
|
||||
{
|
||||
instance = G_OBJECT (g_object_ref (gdk_surface_new_toplevel (display, 100, 100)));
|
||||
instance = G_OBJECT (g_object_ref (gdk_surface_new_toplevel (display)));
|
||||
}
|
||||
else if (g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL) ||
|
||||
g_type_is_a (type, GTK_TYPE_NO_SELECTION) ||
|
||||
|
@ -430,7 +430,7 @@ test_type (gconstpointer data)
|
||||
instance = G_OBJECT (g_object_ref (gtk_settings_get_default ()));
|
||||
else if (g_type_is_a (type, GDK_TYPE_SURFACE))
|
||||
{
|
||||
instance = G_OBJECT (g_object_ref (gdk_surface_new_toplevel (display, 100, 100)));
|
||||
instance = G_OBJECT (g_object_ref (gdk_surface_new_toplevel (display)));
|
||||
}
|
||||
else if (g_str_equal (g_type_name (type), "GdkX11Cursor"))
|
||||
instance = g_object_new (type, "display", display, NULL);
|
||||
|
@ -322,7 +322,7 @@ test_trigger_trigger (void)
|
||||
g_object_ref (trigger[2]));
|
||||
|
||||
device = gdk_seat_get_keyboard (seat);
|
||||
surface = gdk_surface_new_toplevel (display, 100, 100);
|
||||
surface = gdk_surface_new_toplevel (display);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (tests); i++)
|
||||
{
|
||||
|
@ -217,6 +217,16 @@ get_dir_for_file (const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
quit_iteration_loop (gpointer user_data)
|
||||
{
|
||||
gboolean *keep_running = user_data;
|
||||
|
||||
*keep_running = FALSE;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_ui_file (GFile *ui_file,
|
||||
GFile *ref_file,
|
||||
@ -230,6 +240,8 @@ load_ui_file (GFile *ui_file,
|
||||
GError *error = NULL;
|
||||
GtkDirectionType dir;
|
||||
gboolean success = FALSE;
|
||||
gboolean keep_running = TRUE;
|
||||
guint timeout_handle_id;
|
||||
|
||||
ui_path = g_file_get_path (ui_file);
|
||||
|
||||
@ -238,6 +250,19 @@ load_ui_file (GFile *ui_file,
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
timeout_handle_id = g_timeout_add (2000,
|
||||
quit_iteration_loop,
|
||||
&keep_running);
|
||||
while (keep_running)
|
||||
{
|
||||
if (!g_main_context_iteration (NULL, FALSE))
|
||||
break;
|
||||
}
|
||||
if (keep_running)
|
||||
g_source_remove (timeout_handle_id);
|
||||
|
||||
if (ext)
|
||||
{
|
||||
int i;
|
||||
|
Loading…
Reference in New Issue
Block a user