Merge branch 'contentview-step1-finished' into 'main'

[macos] Use system shadow on macOS

Closes #6255

See merge request GNOME/gtk!6785
This commit is contained in:
Benjamin Otte 2024-01-29 18:09:33 +00:00
commit 1ffa01b38a
9 changed files with 114 additions and 29 deletions

View File

@ -77,6 +77,7 @@ enum
PROP_0,
PROP_COMPOSITED,
PROP_RGBA,
PROP_SHADOW_WIDTH,
PROP_INPUT_SHAPES,
PROP_DMABUF_FORMATS,
LAST_PROP
@ -111,6 +112,7 @@ struct _GdkDisplayPrivate {
guint rgba : 1;
guint composited : 1;
guint shadow_width: 1;
guint input_shapes : 1;
GdkDebugFlags debug_flags;
@ -144,6 +146,10 @@ gdk_display_get_property (GObject *object,
g_value_set_boolean (value, gdk_display_is_rgba (display));
break;
case PROP_SHADOW_WIDTH:
g_value_set_boolean (value, gdk_display_supports_shadow_width (display));
break;
case PROP_INPUT_SHAPES:
g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
break;
@ -243,6 +249,18 @@ gdk_display_class_init (GdkDisplayClass *class)
TRUE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDisplay:shadow-width: (attributes org.gtk.Property.get=gdk_display_supports_shadow_width)
*
* %TRUE if the display supports extensible frames.
*
* Since: 4.14
*/
props[PROP_SHADOW_WIDTH] =
g_param_spec_boolean ("shadow-width", NULL, NULL,
TRUE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
* GdkDisplay:input-shapes: (attributes org.gtk.Property.get=gdk_display_supports_input_shapes)
*
@ -391,6 +409,7 @@ gdk_display_init (GdkDisplay *display)
priv->composited = TRUE;
priv->rgba = TRUE;
priv->shadow_width = TRUE;
priv->input_shapes = TRUE;
}
@ -2122,6 +2141,46 @@ gdk_display_set_rgba (GdkDisplay *display,
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_RGBA]);
}
/**
* gdk_display_supports_shadow_width: (attributes org.gtk.Method.get_property=shadow-width)
* @display: a `GdkDisplay`
*
* Returns whether it's possible for a surface to draw outside of the window area.
*
* If %TRUE is returned the application decides if it wants to draw shadows.
* If %FALSE is returned, the compositor decides if it wants to draw shadows.
*
* Returns: %TRUE if surfaces can draw shadows or
* %FALSE if the display does not support this functionality.
*
* Since: 4.14
*/
gboolean
gdk_display_supports_shadow_width (GdkDisplay *display)
{
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
return priv->shadow_width;
}
void
gdk_display_set_shadow_width (GdkDisplay *display,
gboolean shadow_width)
{
GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
g_return_if_fail (GDK_IS_DISPLAY (display));
if (priv->shadow_width == shadow_width)
return;
priv->shadow_width = shadow_width;
g_object_notify_by_pspec (G_OBJECT (display), props[PROP_SHADOW_WIDTH]);
}
static void
device_removed_cb (GdkSeat *seat,
GdkDevice *device,

View File

@ -63,6 +63,8 @@ GDK_AVAILABLE_IN_ALL
gboolean gdk_display_is_composited (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
gboolean gdk_display_is_rgba (GdkDisplay *display);
GDK_AVAILABLE_IN_4_14
gboolean gdk_display_supports_shadow_width (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);

View File

@ -257,6 +257,8 @@ void gdk_display_set_composited (GdkDisplay *display
gboolean composited);
void gdk_display_set_input_shapes (GdkDisplay *display,
gboolean input_shapes);
void gdk_display_set_shadow_width (GdkDisplay *display,
gboolean shadow_width);
void gdk_display_add_seat (GdkDisplay *display,
GdkSeat *seat);

View File

@ -142,6 +142,9 @@ gdk_toplevel_size_set_min_size (GdkToplevelSize *size,
* The shadow width corresponds to the part of the computed surface size
* that would consist of the shadow margin surrounding the window, would
* there be any.
*
* Shadow width should only be set if
* [method@Gtk.Display.supports_shadow_width] is %TRUE.
*/
void
gdk_toplevel_size_set_shadow_width (GdkToplevelSize *size,

View File

@ -398,8 +398,7 @@ typedef NSString *CALayerContentsGravity;
* in from a display-side change. We need to request a layout in
* addition to the configure event.
*/
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface) &&
GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface)->decorated)
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface))
gdk_surface_request_layout (GDK_SURFACE (gdk_surface));
}
@ -875,12 +874,21 @@ typedef NSString *CALayerContentsGravity;
{
NSWindowStyleMask style_mask = [self styleMask];
[self setHasShadow:decorated];
if (decorated)
style_mask |= NSWindowStyleMaskTitled;
{
style_mask &= ~NSWindowStyleMaskFullSizeContentView;
[self setTitleVisibility:NSWindowTitleVisible];
}
else
style_mask &= ~NSWindowStyleMaskTitled;
{
style_mask |= NSWindowStyleMaskFullSizeContentView;
[self setTitleVisibility:NSWindowTitleHidden];
}
[self setTitlebarAppearsTransparent:!decorated];
[[self standardWindowButton:NSWindowCloseButton] setHidden:!decorated];
[[self standardWindowButton:NSWindowMiniaturizeButton] setHidden:!decorated];
[[self standardWindowButton:NSWindowZoomButton] setHidden:!decorated];
[self setStyleMask:style_mask];
}

View File

@ -625,6 +625,7 @@ gdk_macos_display_init (GdkMacosDisplay *self)
gdk_display_set_composited (GDK_DISPLAY (self), TRUE);
gdk_display_set_input_shapes (GDK_DISPLAY (self), FALSE);
gdk_display_set_rgba (GDK_DISPLAY (self), TRUE);
gdk_display_set_shadow_width (GDK_DISPLAY (self), FALSE);
}
GdkDisplay *

View File

@ -1064,6 +1064,7 @@ gdk_win32_display_check_composited (GdkWin32Display *display)
}
gdk_display_set_composited (GDK_DISPLAY (display), composited);
gdk_display_set_shadow_width (GDK_DISPLAY (display), composited);
}
static void

View File

@ -1429,6 +1429,7 @@ gdk_x11_display_open (const char *display_name)
int ignore;
int maj, min;
char *cm_name;
gboolean frame_extents;
XInitThreads ();
@ -1643,6 +1644,10 @@ gdk_x11_display_open (const char *display_name)
gdk_x11_get_xatom_by_name_for_display (display, cm_name)) != None);
g_free (cm_name);
frame_extents = gdk_x11_screen_supports_net_wm_hint (gdk_x11_display_get_screen (display),
g_intern_static_string ("_GTK_FRAME_EXTENTS"));
gdk_display_set_shadow_width (display, frame_extents);
gdk_display_emit_opened (display);
return display;

View File

@ -2949,6 +2949,17 @@ unset_titlebar (GtkWindow *window)
}
}
static gboolean
gtk_window_is_composited (GtkWindow *window)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GdkDisplay *display;
display = priv->display;
return gdk_display_is_rgba (display) && gdk_display_is_composited (display);
}
static gboolean
gtk_window_supports_client_shadow (GtkWindow *window)
{
@ -2957,22 +2968,7 @@ gtk_window_supports_client_shadow (GtkWindow *window)
display = priv->display;
if (!gdk_display_is_rgba (display))
return FALSE;
if (!gdk_display_is_composited (display))
return FALSE;
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (display))
{
if (!gdk_x11_screen_supports_net_wm_hint (gdk_x11_display_get_screen (display),
g_intern_static_string ("_GTK_FRAME_EXTENTS")))
return FALSE;
}
#endif
return TRUE;
return gdk_display_supports_shadow_width (display);
}
static void
@ -2981,11 +2977,15 @@ gtk_window_enable_csd (GtkWindow *window)
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *widget = GTK_WIDGET (window);
/* We need a visual with alpha for client shadows */
if (priv->use_client_shadow)
gtk_widget_add_css_class (widget, "csd");
/* We need a visual with alpha for rounded corners */
if (gtk_window_is_composited (window))
{
gtk_widget_add_css_class (widget, "csd");
}
else
gtk_widget_add_css_class (widget, "solid-csd");
{
gtk_widget_add_css_class (widget, "solid-csd");
}
priv->client_decorated = TRUE;
}
@ -3044,8 +3044,8 @@ gtk_window_set_titlebar (GtkWindow *window,
else
{
priv->use_client_shadow = gtk_window_supports_client_shadow (window);
gtk_window_enable_csd (window);
priv->titlebar = titlebar;
priv->title_box = titlebar;
gtk_widget_insert_before (priv->title_box, widget, NULL);
@ -4298,9 +4298,9 @@ gtk_window_realize (GtkWidget *widget)
/* Create default title bar */
if (!priv->client_decorated && gtk_window_should_use_csd (window))
{
priv->use_client_shadow = gtk_window_supports_client_shadow (window);
if (priv->use_client_shadow)
if (gtk_window_is_composited (window))
{
priv->use_client_shadow = gtk_window_supports_client_shadow (window);
gtk_window_enable_csd (window);
if (priv->title_box == NULL)
@ -4314,6 +4314,8 @@ gtk_window_realize (GtkWidget *widget)
update_window_actions (window);
}
else
priv->use_client_shadow = FALSE;
}
surface = gdk_surface_new_toplevel (gtk_widget_get_display (widget));
@ -4453,6 +4455,8 @@ gtk_window_unrealize (GtkWidget *widget)
gdk_surface_set_widget (surface, NULL);
g_clear_pointer (&priv->surface, gdk_surface_destroy);
priv->use_client_shadow = FALSE;
}
static void