Merge branch 'wip/surface-state-rework' into 'master'

Rework surface state and geometry computation

See merge request GNOME/gtk!2885
This commit is contained in:
Matthias Clasen 2020-12-08 15:38:36 +00:00
commit 1f141c1953
95 changed files with 1713 additions and 2226 deletions

View File

@ -465,7 +465,7 @@ demo_application_window_size_allocate (GtkWidget *widget,
baseline); baseline);
if (!window->maximized && !window->fullscreen) if (!window->maximized && !window->fullscreen)
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height); gtk_window_get_default_size (GTK_WINDOW (window), &window->width, &window->height);
} }
static void static void

View File

@ -97,9 +97,9 @@ demo3_widget_size_allocate (GtkWidget *widget,
/* Since we are not using a layout manager (who would do this /* Since we are not using a layout manager (who would do this
* for us), we need to allocate a size for our menu by calling * for us), we need to allocate a size for our menu by calling
* gtk_native_check_resize(). * gtk_popover_present().
*/ */
gtk_native_check_resize (GTK_NATIVE (self->menu)); gtk_popover_present (GTK_POPOVER (self->menu));
} }
static void static void

View File

@ -474,7 +474,7 @@ suggestion_entry_size_allocate (GtkWidget *widget,
gtk_widget_set_size_request (self->popup, gtk_widget_get_allocated_width (GTK_WIDGET (self)), -1); gtk_widget_set_size_request (self->popup, gtk_widget_get_allocated_width (GTK_WIDGET (self)), -1);
gtk_widget_queue_resize (self->popup); gtk_widget_queue_resize (self->popup);
gtk_native_check_resize (GTK_NATIVE (self->popup)); gtk_popover_present (GTK_POPOVER (self->popup));
} }
static gboolean static gboolean

View File

@ -203,7 +203,6 @@ gdk_surface_get_cursor
gdk_surface_set_input_region gdk_surface_set_input_region
gdk_surface_get_width gdk_surface_get_width
gdk_surface_get_height gdk_surface_get_height
gdk_surface_set_shadow_width
gdk_surface_get_device_position gdk_surface_get_device_position
GdkModifierType GdkModifierType
GDK_MODIFIER_MASK GDK_MODIFIER_MASK
@ -529,7 +528,6 @@ GDK_IS_EVENT
gdk_event_get_type gdk_event_get_type
gdk_event_sequence_get_type gdk_event_sequence_get_type
gdk_button_event_get_type gdk_button_event_get_type
gdk_configure_event_get_type
gdk_crossing_event_get_type gdk_crossing_event_get_type
gdk_delete_event_get_type gdk_delete_event_get_type
gdk_dnd_event_get_type gdk_dnd_event_get_type

View File

@ -4592,6 +4592,7 @@ gtk_window_set_destroy_with_parent
gtk_window_set_display gtk_window_set_display
gtk_window_is_active gtk_window_is_active
gtk_window_is_maximized gtk_window_is_maximized
gtk_window_is_fullscreen
gtk_window_get_toplevels gtk_window_get_toplevels
gtk_window_list_toplevels gtk_window_list_toplevels
gtk_window_get_focus gtk_window_get_focus
@ -4618,12 +4619,10 @@ gtk_window_get_default_size
gtk_window_get_destroy_with_parent gtk_window_get_destroy_with_parent
gtk_window_get_icon_name gtk_window_get_icon_name
gtk_window_get_modal gtk_window_get_modal
gtk_window_get_size
gtk_window_get_title gtk_window_get_title
gtk_window_get_transient_for gtk_window_get_transient_for
gtk_window_get_group gtk_window_get_group
gtk_window_has_group gtk_window_has_group
gtk_window_resize
gtk_window_set_default_icon_name gtk_window_set_default_icon_name
gtk_window_set_icon_name gtk_window_set_icon_name
gtk_window_set_auto_startup_notification gtk_window_set_auto_startup_notification
@ -6116,6 +6115,7 @@ GtkPopover
gtk_popover_new gtk_popover_new
gtk_popover_popup gtk_popover_popup
gtk_popover_popdown gtk_popover_popdown
gtk_popover_present
gtk_popover_set_child gtk_popover_set_child
gtk_popover_get_child gtk_popover_get_child
gtk_popover_set_pointing_to gtk_popover_set_pointing_to
@ -6973,7 +6973,6 @@ GtkNative
gtk_native_get_for_surface gtk_native_get_for_surface
gtk_native_get_surface gtk_native_get_surface
gtk_native_get_renderer gtk_native_get_renderer
gtk_native_check_resize
gtk_native_get_surface_transform gtk_native_get_surface_transform
<SUBSECTION Private> <SUBSECTION Private>

View File

@ -165,7 +165,7 @@ for this change.
| ::key-release-event | #GtkEventControllerKey | | ::key-release-event | #GtkEventControllerKey |
| ::enter-notify-event | #GtkEventControllerMotion | | ::enter-notify-event | #GtkEventControllerMotion |
| ::leave-notify-event | #GtkEventControllerMotion | | ::leave-notify-event | #GtkEventControllerMotion |
| ::configure-event | replaced by #GdkSurface::size-changed | | ::configure-event | replaced by #GdkSurface::layout |
| ::focus-in-event | #GtkEventControllerFocus | | ::focus-in-event | #GtkEventControllerFocus |
| ::focus-out-event | #GtkEventControllerFocus | | ::focus-out-event | #GtkEventControllerFocus |
| ::map-event | replaced by #GdkSurface:mapped | | ::map-event | replaced by #GdkSurface:mapped |
@ -510,9 +510,14 @@ gtk_window_set_gravity(), gtk_window_move(), gtk_window_parse_geometry(),
gtk_window_set_keep_above(), gtk_window_set_keep_below(), gtk_window_set_keep_above(), gtk_window_set_keep_below(),
gtk_window_begin_resize_drag(), gtk_window_begin_move_drag(). gtk_window_begin_resize_drag(), gtk_window_begin_move_drag().
Most likely, you should just stop using them. In some cases, you can Most likely, you should just stop using them. In some cases, you can
fall back to using the underlying #GdkToplevel APIS (for example, fall back to using the underlying #GdkToplevel APIs (for example,
gdk_toplevel_begin_resize()). gdk_toplevel_begin_resize()).
The APIs for controlling GtkWindow size have changed to be better aligned
with the way size changes are integrated in the frame cycle. gtk_window_resize()
and gtk_window_get_size() have been removed. Instead, use
gtk_window_set_default_size() and gtk_window_get_default_size().
### Adapt to GtkHeaderBar and GtkActionBar API changes ### Adapt to GtkHeaderBar and GtkActionBar API changes
The gtk_header_bar_set_show_close_button() function has been renamed to The gtk_header_bar_set_show_close_button() function has been renamed to

View File

@ -12,13 +12,6 @@ gtk_widget_set_size_request():
we use 1x1 for implementation convenience) we use 1x1 for implementation convenience)
- causes notifies on width_request, height_request properties - causes notifies on width_request, height_request properties
gtk_window_resize():
- causes a configure request in all cases if the window is mapped,
unless the new size is the same as the old size
- overrides the default size on map if the window is unmapped
- allows size of 0, equivalent to 1
- clamped to geometry hints
gtk_window_set_default_size(): gtk_window_set_default_size():
- has no effect after the window has been mapped the first time, - has no effect after the window has been mapped the first time,
unless the window has been unrealized in which case it should unless the window has been unrealized in which case it should
@ -26,7 +19,6 @@ gtk_window_set_default_size():
- allows size of 0, equivalent to 1 - allows size of 0, equivalent to 1
- allows size of -1 to unset the default size - allows size of -1 to unset the default size
- clamped to geometry hints - clamped to geometry hints
- gtk_window_resize() overrides it
- causes notifies on default_width, default_height properties - causes notifies on default_width, default_height properties
gtk_window_get_default_size(): gtk_window_get_default_size():

View File

@ -280,12 +280,7 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
surface = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->configure_notify.id)); surface = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->configure_notify.id));
if (surface) if (surface)
{ {
event = gdk_configure_event_new (surface, gdk_surface_request_layout (surface);
message->configure_notify.width,
message->configure_notify.height);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
if (surface->resize_count >= 1) if (surface->resize_count >= 1)
{ {

View File

@ -558,6 +558,7 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
int height, int height,
GdkPopupLayout *layout) GdkPopupLayout *layout)
{ {
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkMonitor *monitor; GdkMonitor *monitor;
GdkRectangle bounds; GdkRectangle bounds;
GdkRectangle final_rect; GdkRectangle final_rect;
@ -570,6 +571,10 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface, gdk_surface_layout_popup_helper (surface,
width, width,
height, height,
impl->shadow_left,
impl->shadow_right,
impl->shadow_top,
impl->shadow_bottom,
monitor, monitor,
&bounds, &bounds,
layout, layout,
@ -596,7 +601,7 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
static void static void
show_popup (GdkSurface *surface) show_popup (GdkSurface *surface)
{ {
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (surface, TRUE);
gdk_broadway_surface_show (surface, FALSE); gdk_broadway_surface_show (surface, FALSE);
gdk_surface_invalidate_rect (surface, NULL); gdk_surface_invalidate_rect (surface, NULL);
} }
@ -1516,7 +1521,7 @@ show_surface (GdkSurface *surface)
was_mapped = GDK_SURFACE_IS_MAPPED (surface); was_mapped = GDK_SURFACE_IS_MAPPED (surface);
if (!was_mapped) if (!was_mapped)
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (surface, TRUE);
gdk_broadway_surface_show (surface, FALSE); gdk_broadway_surface_show (surface, FALSE);
@ -1524,11 +1529,12 @@ show_surface (GdkSurface *surface)
gdk_surface_invalidate_rect (surface, NULL); gdk_surface_invalidate_rect (surface, NULL);
} }
static gboolean static void
gdk_broadway_toplevel_present (GdkToplevel *toplevel, gdk_broadway_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout) GdkToplevelLayout *layout)
{ {
GdkSurface *surface = GDK_SURFACE (toplevel); GdkSurface *surface = GDK_SURFACE (toplevel);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface); GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor; GdkMonitor *monitor;
GdkToplevelSize size; GdkToplevelSize size;
@ -1582,9 +1588,15 @@ gdk_broadway_toplevel_present (GdkToplevel *toplevel,
else else
gdk_broadway_surface_unmaximize (surface); gdk_broadway_surface_unmaximize (surface);
show_surface (surface); if (size.shadow.is_valid)
{
impl->shadow_left = size.shadow.left;
impl->shadow_right = size.shadow.right;
impl->shadow_top = size.shadow.top;
impl->shadow_bottom = size.shadow.bottom;
}
return TRUE; show_surface (surface);
} }
static gboolean static gboolean

View File

@ -64,6 +64,11 @@ struct _GdkBroadwaySurface
int root_x; int root_x;
int root_y; int root_y;
int shadow_left;
int shadow_right;
int shadow_top;
int shadow_bottom;
}; };
struct _GdkBroadwaySurfaceClass struct _GdkBroadwaySurfaceClass

View File

@ -15,9 +15,6 @@ gboolean gdk_device_grab_info (GdkDisplay *display,
void gdk_pre_parse (void); void gdk_pre_parse (void);
void gdk_surface_freeze_toplevel_updates (GdkSurface *surface);
void gdk_surface_thaw_toplevel_updates (GdkSurface *surface);
gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface); gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface);
void gdk_display_set_double_click_time (GdkDisplay *display, void gdk_display_set_double_click_time (GdkDisplay *display,

View File

@ -54,12 +54,11 @@ typedef enum
GDK_PROPERTY_CHANGE_MASK = 1 << 16, GDK_PROPERTY_CHANGE_MASK = 1 << 16,
GDK_PROXIMITY_IN_MASK = 1 << 18, GDK_PROXIMITY_IN_MASK = 1 << 18,
GDK_PROXIMITY_OUT_MASK = 1 << 19, GDK_PROXIMITY_OUT_MASK = 1 << 19,
GDK_SUBSTRUCTURE_MASK = 1 << 20, GDK_SCROLL_MASK = 1 << 20,
GDK_SCROLL_MASK = 1 << 21, GDK_TOUCH_MASK = 1 << 21,
GDK_TOUCH_MASK = 1 << 22, GDK_SMOOTH_SCROLL_MASK = 1 << 22,
GDK_SMOOTH_SCROLL_MASK = 1 << 23, GDK_TOUCHPAD_GESTURE_MASK = 1 << 23,
GDK_TOUCHPAD_GESTURE_MASK = 1 << 24, GDK_TABLET_PAD_MASK = 1 << 24,
GDK_TABLET_PAD_MASK = 1 << 25,
GDK_ALL_EVENTS_MASK = 0x3FFFFFE GDK_ALL_EVENTS_MASK = 0x3FFFFFE
} GdkEventMask; } GdkEventMask;

View File

@ -430,7 +430,6 @@ static void
gdk_event_init_types_once (void) gdk_event_init_types_once (void)
{ {
g_type_ensure (GDK_TYPE_BUTTON_EVENT); g_type_ensure (GDK_TYPE_BUTTON_EVENT);
g_type_ensure (GDK_TYPE_CONFIGURE_EVENT);
g_type_ensure (GDK_TYPE_CROSSING_EVENT); g_type_ensure (GDK_TYPE_CROSSING_EVENT);
g_type_ensure (GDK_TYPE_DELETE_EVENT); g_type_ensure (GDK_TYPE_DELETE_EVENT);
g_type_ensure (GDK_TYPE_DND_EVENT); g_type_ensure (GDK_TYPE_DND_EVENT);
@ -1818,76 +1817,6 @@ gdk_key_event_get_match (GdkEvent *event,
/* }}} */ /* }}} */
/* {{{ GdkConfigureEvent */
static gboolean
gdk_configure_event_get_position (GdkEvent *event,
double *x,
double *y)
{
GdkConfigureEvent *self = (GdkConfigureEvent *) event;
*x = self->x;
*y = self->y;
return TRUE;
}
static const GdkEventTypeInfo gdk_configure_event_info = {
sizeof (GdkConfigureEvent),
NULL,
NULL,
NULL,
gdk_configure_event_get_position,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkConfigureEvent, gdk_configure_event,
&gdk_configure_event_info,
GDK_EVENT_TYPE_SLOT (GDK_CONFIGURE))
GdkEvent *
gdk_configure_event_new (GdkSurface *surface,
int width,
int height)
{
GdkConfigureEvent *self;
g_return_val_if_fail (width >= 0 && height >= 0, NULL);
self = gdk_event_alloc (GDK_CONFIGURE, surface, NULL, GDK_CURRENT_TIME);
self->width = width;
self->height = height;
return (GdkEvent *) self;
}
/**
* gdk_configure_event_get_size:
* @event: (type GdkConfigureEvent): a configure event
* @width: (out): return location for surface width
* @height: (out): return location for surface height
*
* Extracts the surface size from a configure event.
*/
void
gdk_configure_event_get_size (GdkEvent *event,
int *width,
int *height)
{
GdkConfigureEvent *self = (GdkConfigureEvent *) event;
g_return_if_fail (GDK_IS_EVENT (event));
g_return_if_fail (GDK_IS_EVENT_TYPE (event, GDK_CONFIGURE));
*width = self->width;
*height = self->height;
}
/* }}} */
/* {{{ GdkTouchEvent */ /* {{{ GdkTouchEvent */
static void static void

View File

@ -106,7 +106,6 @@ typedef struct _GdkEventSequence GdkEventSequence;
typedef struct _GdkEvent GdkEvent; typedef struct _GdkEvent GdkEvent;
#define GDK_TYPE_BUTTON_EVENT (gdk_button_event_get_type()) #define GDK_TYPE_BUTTON_EVENT (gdk_button_event_get_type())
#define GDK_TYPE_CONFIGURE_EVENT (gdk_configure_event_get_type())
#define GDK_TYPE_CROSSING_EVENT (gdk_crossing_event_get_type()) #define GDK_TYPE_CROSSING_EVENT (gdk_crossing_event_get_type())
#define GDK_TYPE_DELETE_EVENT (gdk_delete_event_get_type()) #define GDK_TYPE_DELETE_EVENT (gdk_delete_event_get_type())
#define GDK_TYPE_DND_EVENT (gdk_dnd_event_get_type()) #define GDK_TYPE_DND_EVENT (gdk_dnd_event_get_type())
@ -121,7 +120,6 @@ typedef struct _GdkEvent GdkEvent;
#define GDK_TYPE_TOUCHPAD_EVENT (gdk_touchpad_event_get_type()) #define GDK_TYPE_TOUCHPAD_EVENT (gdk_touchpad_event_get_type())
typedef struct _GdkButtonEvent GdkButtonEvent; typedef struct _GdkButtonEvent GdkButtonEvent;
typedef struct _GdkConfigureEvent GdkConfigureEvent;
typedef struct _GdkCrossingEvent GdkCrossingEvent; typedef struct _GdkCrossingEvent GdkCrossingEvent;
typedef struct _GdkDeleteEvent GdkDeleteEvent; typedef struct _GdkDeleteEvent GdkDeleteEvent;
typedef struct _GdkDNDEvent GdkDNDEvent; typedef struct _GdkDNDEvent GdkDNDEvent;
@ -148,7 +146,6 @@ typedef struct _GdkTouchpadEvent GdkTouchpadEvent;
* @GDK_ENTER_NOTIFY: the pointer has entered the surface. * @GDK_ENTER_NOTIFY: the pointer has entered the surface.
* @GDK_LEAVE_NOTIFY: the pointer has left the surface. * @GDK_LEAVE_NOTIFY: the pointer has left the surface.
* @GDK_FOCUS_CHANGE: the keyboard focus has entered or left the surface. * @GDK_FOCUS_CHANGE: the keyboard focus has entered or left the surface.
* @GDK_CONFIGURE: the size of the surface has changed.
* @GDK_PROXIMITY_IN: an input device has moved into contact with a sensing * @GDK_PROXIMITY_IN: an input device has moved into contact with a sensing
* surface (e.g. a touchscreen or graphics tablet). * surface (e.g. a touchscreen or graphics tablet).
* @GDK_PROXIMITY_OUT: an input device has moved out of contact with a sensing * @GDK_PROXIMITY_OUT: an input device has moved out of contact with a sensing
@ -188,7 +185,6 @@ typedef enum
GDK_ENTER_NOTIFY, GDK_ENTER_NOTIFY,
GDK_LEAVE_NOTIFY, GDK_LEAVE_NOTIFY,
GDK_FOCUS_CHANGE, GDK_FOCUS_CHANGE,
GDK_CONFIGURE,
GDK_PROXIMITY_IN, GDK_PROXIMITY_IN,
GDK_PROXIMITY_OUT, GDK_PROXIMITY_OUT,
GDK_DRAG_ENTER, GDK_DRAG_ENTER,
@ -429,12 +425,6 @@ GdkNotifyType gdk_crossing_event_get_detail (GdkEvent *event);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
gboolean gdk_crossing_event_get_focus (GdkEvent *event); gboolean gdk_crossing_event_get_focus (GdkEvent *event);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GType gdk_configure_event_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
void gdk_configure_event_get_size (GdkEvent *event,
int *width,
int *height);
GDK_AVAILABLE_IN_ALL
GType gdk_touchpad_event_get_type (void) G_GNUC_CONST; GType gdk_touchpad_event_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GdkTouchpadGesturePhase GdkTouchpadGesturePhase

View File

@ -322,25 +322,6 @@ struct _GdkFocusEvent
gboolean focus_in; gboolean focus_in;
}; };
/*
* GdkConfigureEvent:
* @x: the new x coordinate of the surface, relative to its parent.
* @y: the new y coordinate of the surface, relative to its parent.
* @width: the new width of the surface.
* @height: the new height of the surface.
*
* Generated when a surface size or position has changed.
*/
struct _GdkConfigureEvent
{
GdkEvent parent_instance;
int x;
int y;
int width;
int height;
};
/* /*
* GdkProximityEvent: * GdkProximityEvent:
* @tool: the #GdkDeviceTool associated to the event * @tool: the #GdkDeviceTool associated to the event

View File

@ -50,7 +50,7 @@ typedef struct _GdkFrameClockClass GdkFrameClockClass;
* @GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS: corresponds to GdkFrameClock::flush-events. Should not be handled by applications. * @GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS: corresponds to GdkFrameClock::flush-events. Should not be handled by applications.
* @GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT: corresponds to GdkFrameClock::before-paint. Should not be handled by applications. * @GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT: corresponds to GdkFrameClock::before-paint. Should not be handled by applications.
* @GDK_FRAME_CLOCK_PHASE_UPDATE: corresponds to GdkFrameClock::update. * @GDK_FRAME_CLOCK_PHASE_UPDATE: corresponds to GdkFrameClock::update.
* @GDK_FRAME_CLOCK_PHASE_LAYOUT: corresponds to GdkFrameClock::layout. * @GDK_FRAME_CLOCK_PHASE_LAYOUT: corresponds to GdkFrameClock::layout. Should not be handled by applicatiosn.
* @GDK_FRAME_CLOCK_PHASE_PAINT: corresponds to GdkFrameClock::paint. * @GDK_FRAME_CLOCK_PHASE_PAINT: corresponds to GdkFrameClock::paint.
* @GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS: corresponds to GdkFrameClock::resume-events. Should not be handled by applications. * @GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS: corresponds to GdkFrameClock::resume-events. Should not be handled by applications.
* @GDK_FRAME_CLOCK_PHASE_AFTER_PAINT: corresponds to GdkFrameClock::after-paint. Should not be handled by applications. * @GDK_FRAME_CLOCK_PHASE_AFTER_PAINT: corresponds to GdkFrameClock::after-paint. Should not be handled by applications.

View File

@ -38,15 +38,6 @@
G_DEFINE_INTERFACE (GdkPopup, gdk_popup, GDK_TYPE_SURFACE) G_DEFINE_INTERFACE (GdkPopup, gdk_popup, GDK_TYPE_SURFACE)
enum
{
POPUP_LAYOUT_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS] = { 0 };
static gboolean static gboolean
gdk_popup_default_present (GdkPopup *popup, gdk_popup_default_present (GdkPopup *popup,
int width, int width,
@ -101,25 +92,6 @@ gdk_popup_default_init (GdkPopupInterface *iface)
P_("Whether to hide on outside clicks"), P_("Whether to hide on outside clicks"),
FALSE, FALSE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
/**
* GdkPopup::popup-layout-changed
* @popup: the #GdkSurface that was laid out
*
* Emitted when the layout of a popup surface has changed, e.g. if the popup
* layout was reactive and after the parent moved causing the popover to end
* up partially off-screen.
*/
signals[POPUP_LAYOUT_CHANGED] =
g_signal_new (g_intern_static_string ("popup-layout-changed"),
GDK_TYPE_POPUP,
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
} }
/** /**
@ -133,13 +105,16 @@ gdk_popup_default_init (GdkPopupInterface *iface)
* If the popup was previously now showing, it will be showed, * If the popup was previously now showing, it will be showed,
* otherwise it will change position according to @layout. * otherwise it will change position according to @layout.
* *
* After calling this function, the result of the layout can be queried * After calling this function, the result should be handled in response
* using gdk_popup_get_position_x(), gdk_popup_get_position_y(), * to the #GdkSurface::layout signal being emitted. The resulting popup
* gdk_surface_get_width(), gdk_surface_get_height(), * position can be queried using gdk_popup_get_position_x(),
* gdk_popup_get_rect_anchor() and gdk_popup_get_surface_anchor(). * gdk_popup_get_position_y(), and the resulting size will be sent as
* parameters in the layout signal. Use gdk_popup_get_rect_anchor() and
* gdk_popup_get_surface_anchor() to get the resulting anchors.
* *
* Presenting may have fail, for example if it was immediately * Presenting may fail, for example if the @popup is set to autohide
* hidden if the @popup was set to autohide. * and is immediately hidden upon being presented. If presenting failed,
* the #GdkSurface::layout signal will not me emitted.
* *
* Returns: %FALSE if it failed to be presented, otherwise %TRUE. * Returns: %FALSE if it failed to be presented, otherwise %TRUE.
*/ */
@ -164,7 +139,7 @@ gdk_popup_present (GdkPopup *popup,
* Gets the current popup surface anchor. * Gets the current popup surface anchor.
* *
* The value returned may change after calling gdk_popup_present(), * The value returned may change after calling gdk_popup_present(),
* or after the "popup-layout-changed" is emitted. * or after the #GdkSurface::layout signal is emitted.
* *
* Returns: the current surface anchor value of @popup * Returns: the current surface anchor value of @popup
*/ */
@ -183,7 +158,7 @@ gdk_popup_get_surface_anchor (GdkPopup *popup)
* Gets the current popup rectangle anchor. * Gets the current popup rectangle anchor.
* *
* The value returned may change after calling gdk_popup_present(), * The value returned may change after calling gdk_popup_present(),
* or after the "popup-layout-changed" is emitted. * or after the #GdkSurface::layout signal is emitted.
* *
* Returns: the current rectangle anchor value of @popup * Returns: the current rectangle anchor value of @popup
*/ */

View File

@ -76,8 +76,7 @@
*/ */
enum { enum {
POPUP_LAYOUT_CHANGED, LAYOUT,
SIZE_CHANGED,
RENDER, RENDER,
EVENT, EVENT,
ENTER_MONITOR, ENTER_MONITOR,
@ -115,6 +114,9 @@ static void update_cursor (GdkDisplay *display,
static void gdk_surface_set_frame_clock (GdkSurface *surface, static void gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock); GdkFrameClock *clock);
static void gdk_surface_queue_set_is_mapped (GdkSurface *surface,
gboolean is_mapped);
static guint signals[LAST_SIGNAL] = { 0 }; static guint signals[LAST_SIGNAL] = { 0 };
static GParamSpec *properties[LAST_PROP] = { NULL, }; static GParamSpec *properties[LAST_PROP] = { NULL, };
@ -285,6 +287,10 @@ void
gdk_surface_layout_popup_helper (GdkSurface *surface, gdk_surface_layout_popup_helper (GdkSurface *surface,
int width, int width,
int height, int height,
int shadow_left,
int shadow_right,
int shadow_top,
int shadow_bottom,
GdkMonitor *monitor, GdkMonitor *monitor,
GdkRectangle *bounds, GdkRectangle *bounds,
GdkPopupLayout *layout, GdkPopupLayout *layout,
@ -315,8 +321,8 @@ gdk_surface_layout_popup_helper (GdkSurface *surface,
gdk_popup_layout_get_offset (layout, &rect_anchor_dx, &rect_anchor_dy); gdk_popup_layout_get_offset (layout, &rect_anchor_dx, &rect_anchor_dy);
anchor_hints = gdk_popup_layout_get_anchor_hints (layout); anchor_hints = gdk_popup_layout_get_anchor_hints (layout);
final_rect.width = width - surface->shadow_left - surface->shadow_right; final_rect.width = width - shadow_left - shadow_right;
final_rect.height = height - surface->shadow_top - surface->shadow_bottom; final_rect.height = height - shadow_top - shadow_bottom;
final_rect.x = maybe_flip_position (bounds->x, final_rect.x = maybe_flip_position (bounds->x,
bounds->width, bounds->width,
root_rect.x, root_rect.x,
@ -380,10 +386,10 @@ gdk_surface_layout_popup_helper (GdkSurface *surface,
final_rect.height = bounds->y + bounds->height - final_rect.y; final_rect.height = bounds->y + bounds->height - final_rect.y;
} }
final_rect.x -= surface->shadow_left; final_rect.x -= shadow_left;
final_rect.y -= surface->shadow_top; final_rect.y -= shadow_top;
final_rect.width += surface->shadow_left + surface->shadow_right; final_rect.width += shadow_left + shadow_right;
final_rect.height += surface->shadow_top + surface->shadow_bottom; final_rect.height += shadow_top + shadow_bottom;
gdk_surface_get_origin (surface->parent, &x, &y); gdk_surface_get_origin (surface->parent, &x, &y);
final_rect.x -= x; final_rect.x -= x;
@ -469,7 +475,7 @@ gdk_surface_init (GdkSurface *surface)
{ {
/* 0-initialization is good for all other fields. */ /* 0-initialization is good for all other fields. */
surface->state = GDK_TOPLEVEL_STATE_WITHDRAWN; surface->state = 0;
surface->fullscreen_mode = GDK_FULLSCREEN_ON_CURRENT_MONITOR; surface->fullscreen_mode = GDK_FULLSCREEN_ON_CURRENT_MONITOR;
surface->width = 1; surface->width = 1;
surface->height = 1; surface->height = 1;
@ -548,18 +554,19 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
g_object_class_install_properties (object_class, LAST_PROP, properties); g_object_class_install_properties (object_class, LAST_PROP, properties);
/** /**
* GdkSurface::size-changed: * GdkSurface::layout:
* @surface: the #GdkSurface * @surface: the #GdkSurface
* @width: the new width * @width: the current width
* @height: the new height * @height: the current height
* *
* Emitted when the size of @surface is changed. * Emitted when the size of @surface is changed, or when relayout should
* be performed.
* *
* Surface size is reported in application pixels, not * Surface size is reported in application pixels, not
* device pixels (see gdk_surface_get_scale_factor()). * device pixels (see gdk_surface_get_scale_factor()).
*/ */
signals[SIZE_CHANGED] = signals[LAYOUT] =
g_signal_new (g_intern_static_string ("size-changed"), g_signal_new (g_intern_static_string ("layout"),
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
0, 0,
@ -919,7 +926,10 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface,
_gdk_surface_clear_update_area (surface); _gdk_surface_clear_update_area (surface);
surface->state |= GDK_TOPLEVEL_STATE_WITHDRAWN; g_clear_handle_id (&surface->set_is_mapped_source_id, g_source_remove);
surface->is_mapped = FALSE;
surface->pending_is_mapped = FALSE;
surface->destroyed = TRUE; surface->destroyed = TRUE;
surface_remove_from_pointer_info (surface, surface->display); surface_remove_from_pointer_info (surface, surface->display);
@ -1264,7 +1274,7 @@ gdk_surface_schedule_update (GdkSurface *surface)
if (surface->update_freeze_count || if (surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface)) gdk_surface_is_toplevel_frozen (surface))
{ {
surface->pending_schedule_update = TRUE; surface->pending_phases |= GDK_FRAME_CLOCK_PHASE_PAINT;
return; return;
} }
@ -1317,6 +1327,50 @@ gdk_surface_process_updates_internal (GdkSurface *surface)
g_object_unref (surface); g_object_unref (surface);
} }
static void
gdk_surface_layout_on_clock (GdkFrameClock *clock,
void *data)
{
GdkSurface *surface = GDK_SURFACE (data);
GdkSurfaceClass *class;
g_return_if_fail (GDK_IS_SURFACE (surface));
if (GDK_SURFACE_DESTROYED (surface))
return;
if (!GDK_SURFACE_IS_MAPPED (surface))
return;
surface->pending_phases &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
class = GDK_SURFACE_GET_CLASS (surface);
if (class->compute_size)
{
if (class->compute_size (surface))
return;
}
g_signal_emit (surface, signals[LAYOUT], 0, surface->width, surface->height);
}
void
gdk_surface_request_layout (GdkSurface *surface)
{
GdkSurfaceClass *class;
GdkFrameClock *frame_clock;
class = GDK_SURFACE_GET_CLASS (surface);
if (class->request_layout)
class->request_layout (surface);
frame_clock = gdk_surface_get_frame_clock (surface);
g_return_if_fail (frame_clock);
gdk_frame_clock_request_phase (frame_clock,
GDK_FRAME_CLOCK_PHASE_LAYOUT);
}
static void static void
gdk_surface_paint_on_clock (GdkFrameClock *clock, gdk_surface_paint_on_clock (GdkFrameClock *clock,
void *data) void *data)
@ -1338,6 +1392,7 @@ gdk_surface_paint_on_clock (GdkFrameClock *clock,
* do the update later when idle instead. */ * do the update later when idle instead. */
!surface->in_update) !surface->in_update)
{ {
surface->pending_phases &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
gdk_surface_process_updates_internal (surface); gdk_surface_process_updates_internal (surface);
gdk_surface_remove_update_surface (surface); gdk_surface_remove_update_surface (surface);
} }
@ -1515,37 +1570,15 @@ gdk_surface_thaw_updates (GdkSurface *surface)
if (--surface->update_freeze_count == 0) if (--surface->update_freeze_count == 0)
{ {
_gdk_frame_clock_inhibit_freeze (surface->frame_clock); GdkFrameClock *frame_clock = surface->frame_clock;
if (surface->pending_schedule_update) _gdk_frame_clock_inhibit_freeze (frame_clock);
{
surface->pending_schedule_update = FALSE; if (surface->pending_phases)
gdk_surface_schedule_update (surface); gdk_frame_clock_request_phase (frame_clock, surface->pending_phases);
}
} }
} }
void
gdk_surface_freeze_toplevel_updates (GdkSurface *surface)
{
g_return_if_fail (GDK_IS_SURFACE (surface));
surface->update_and_descendants_freeze_count++;
gdk_surface_freeze_updates (surface);
}
void
gdk_surface_thaw_toplevel_updates (GdkSurface *surface)
{
g_return_if_fail (GDK_IS_SURFACE (surface));
g_return_if_fail (surface->update_and_descendants_freeze_count > 0);
surface->update_and_descendants_freeze_count--;
gdk_surface_schedule_update (surface);
gdk_surface_thaw_updates (surface);
}
/* /*
* gdk_surface_constrain_size: * gdk_surface_constrain_size:
* @geometry: a #GdkGeometry structure * @geometry: a #GdkGeometry structure
@ -1669,8 +1702,7 @@ gdk_surface_hide (GdkSurface *surface)
was_mapped = GDK_SURFACE_IS_MAPPED (surface); was_mapped = GDK_SURFACE_IS_MAPPED (surface);
if (GDK_SURFACE_IS_MAPPED (surface)) gdk_surface_queue_set_is_mapped (surface, FALSE);
gdk_synthesize_surface_state (surface, 0, GDK_TOPLEVEL_STATE_WITHDRAWN);
if (was_mapped) if (was_mapped)
{ {
@ -2411,6 +2443,10 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
"resume-events", "resume-events",
G_CALLBACK (gdk_surface_resume_events), G_CALLBACK (gdk_surface_resume_events),
surface); surface);
g_signal_connect (G_OBJECT (clock),
"layout",
G_CALLBACK (gdk_surface_layout_on_clock),
surface);
g_signal_connect (G_OBJECT (clock), g_signal_connect (G_OBJECT (clock),
"paint", "paint",
G_CALLBACK (gdk_surface_paint_on_clock), G_CALLBACK (gdk_surface_paint_on_clock),
@ -2431,6 +2467,9 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock), g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_resume_events), G_CALLBACK (gdk_surface_resume_events),
surface); surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_layout_on_clock),
surface);
g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock), g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
G_CALLBACK (gdk_surface_paint_on_clock), G_CALLBACK (gdk_surface_paint_on_clock),
surface); surface);
@ -2570,58 +2609,10 @@ gdk_surface_set_opaque_region (GdkSurface *surface,
class->set_opaque_region (surface, region); class->set_opaque_region (surface, region);
} }
/**
* gdk_surface_set_shadow_width:
* @surface: a #GdkSurface
* @left: The left extent
* @right: The right extent
* @top: The top extent
* @bottom: The bottom extent
*
* Newer GTK windows using client-side decorations use extra geometry
* around their frames for effects like shadows and invisible borders.
* Window managers that want to maximize windows or snap to edges need
* to know where the extents of the actual frame lie, so that users
* dont feel like windows are snapping against random invisible edges.
*
* Note that this property is automatically updated by GTK, so this
* function should only be used by applications which do not use GTK
* to create toplevel surfaces.
*/
void
gdk_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom)
{
GdkSurfaceClass *class;
g_return_if_fail (GDK_IS_SURFACE (surface));
g_return_if_fail (!GDK_SURFACE_DESTROYED (surface));
g_return_if_fail (left >= 0 && right >= 0 && top >= 0 && bottom >= 0);
if (surface->shadow_left == left &&
surface->shadow_right == right &&
surface->shadow_top == top &&
surface->shadow_bottom == bottom)
return;
surface->shadow_top = top;
surface->shadow_left = left;
surface->shadow_right = right;
surface->shadow_bottom = bottom;
class = GDK_SURFACE_GET_CLASS (surface);
if (class->set_shadow_width)
class->set_shadow_width (surface, left, right, top, bottom);
}
void void
gdk_surface_set_state (GdkSurface *surface, gdk_surface_set_state (GdkSurface *surface,
GdkToplevelState new_state) GdkToplevelState new_state)
{ {
gboolean was_mapped, mapped;
gboolean was_sticky, sticky; gboolean was_sticky, sticky;
g_return_if_fail (GDK_IS_SURFACE (surface)); g_return_if_fail (GDK_IS_SURFACE (surface));
@ -2633,20 +2624,15 @@ gdk_surface_set_state (GdkSurface *surface,
* inconsistent state to the user. * inconsistent state to the user.
*/ */
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
was_sticky = GDK_SURFACE_IS_STICKY (surface); was_sticky = GDK_SURFACE_IS_STICKY (surface);
surface->state = new_state; surface->state = new_state;
mapped = GDK_SURFACE_IS_MAPPED (surface);
sticky = GDK_SURFACE_IS_STICKY (surface); sticky = GDK_SURFACE_IS_STICKY (surface);
if (GDK_IS_TOPLEVEL (surface)) if (GDK_IS_TOPLEVEL (surface))
g_object_notify (G_OBJECT (surface), "state"); 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) if (was_sticky != sticky)
g_object_notify (G_OBJECT (surface), "sticky"); g_object_notify (G_OBJECT (surface), "sticky");
} }
@ -2659,6 +2645,94 @@ gdk_synthesize_surface_state (GdkSurface *surface,
gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags); gdk_surface_set_state (surface, (surface->state | set_flags) & ~unset_flags);
} }
void
gdk_surface_queue_state_change (GdkSurface *surface,
GdkToplevelState unset_flags,
GdkToplevelState set_flags)
{
surface->pending_unset_flags |= unset_flags;
surface->pending_set_flags &= ~unset_flags;
surface->pending_set_flags |= set_flags;
surface->pending_unset_flags &= ~set_flags;
}
void
gdk_surface_apply_state_change (GdkSurface *surface)
{
if (!surface->pending_unset_flags && !surface->pending_set_flags)
return;
gdk_synthesize_surface_state (surface,
surface->pending_unset_flags,
surface->pending_set_flags);
surface->pending_unset_flags = 0;
surface->pending_set_flags = 0;
}
static gboolean
set_is_mapped_idle (gpointer user_data)
{
GdkSurface *surface = GDK_SURFACE (user_data);
surface->set_is_mapped_source_id = 0;
g_return_val_if_fail (surface->pending_is_mapped != surface->is_mapped,
G_SOURCE_REMOVE);
surface->is_mapped = surface->pending_is_mapped;
if (surface->is_mapped)
gdk_surface_invalidate_rect (surface, NULL);
g_object_notify (G_OBJECT (surface), "mapped");
return G_SOURCE_REMOVE;
}
void
gdk_surface_set_is_mapped (GdkSurface *surface,
gboolean is_mapped)
{
gboolean was_mapped;
if (surface->pending_is_mapped != surface->is_mapped)
g_clear_handle_id (&surface->set_is_mapped_source_id, g_source_remove);
surface->pending_is_mapped = is_mapped;
was_mapped = surface->is_mapped;
surface->is_mapped = is_mapped;
if (surface->is_mapped)
gdk_surface_invalidate_rect (surface, NULL);
if (was_mapped != is_mapped)
g_object_notify (G_OBJECT (surface), "mapped");
}
static void
gdk_surface_queue_set_is_mapped (GdkSurface *surface,
gboolean is_mapped)
{
if (surface->pending_is_mapped == is_mapped)
return;
surface->pending_is_mapped = is_mapped;
if (surface->is_mapped == surface->pending_is_mapped)
{
g_clear_handle_id (&surface->set_is_mapped_source_id, g_source_remove);
}
else
{
g_return_if_fail (!surface->set_is_mapped_source_id);
surface->set_is_mapped_source_id =
g_idle_add_full (G_PRIORITY_HIGH - 10,
set_is_mapped_idle,
surface, NULL);
}
}
static gboolean static gboolean
check_autohide (GdkEvent *event) check_autohide (GdkEvent *event)
{ {
@ -2770,14 +2844,6 @@ add_event_mark (GdkEvent *event,
break; break;
} }
case GDK_CONFIGURE:
{
int width, height;
gdk_configure_event_get_size (event, &width, &height);
message = g_strdup_printf ("%s {width=%d, height=%d}", kind, width, height);
break;
}
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY: case GDK_LEAVE_NOTIFY:
case GDK_TOUCHPAD_SWIPE: case GDK_TOUCHPAD_SWIPE:
@ -2815,30 +2881,18 @@ add_event_mark (GdkEvent *event,
gboolean gboolean
gdk_surface_handle_event (GdkEvent *event) gdk_surface_handle_event (GdkEvent *event)
{ {
GdkSurface *surface = gdk_event_get_surface (event);
gint64 begin_time = GDK_PROFILER_CURRENT_TIME; gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
gboolean handled = FALSE; gboolean handled = FALSE;
if (check_autohide (event)) if (check_autohide (event))
return TRUE; return TRUE;
if (gdk_event_get_event_type (event) == GDK_CONFIGURE)
{
int width, height;
gdk_configure_event_get_size (event, &width, &height); if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY)
g_signal_emit (gdk_event_get_surface (event), signals[SIZE_CHANGED], 0, surface->request_motion = FALSE;
width, height);
handled = TRUE;
}
else
{
GdkSurface *surface = gdk_event_get_surface (event);
if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY) g_signal_emit (surface, signals[EVENT], 0, event, &handled);
surface->request_motion = FALSE;
g_signal_emit (surface, signals[EVENT], 0, event, &handled);
}
if (GDK_PROFILER_IS_RUNNING) if (GDK_PROFILER_IS_RUNNING)
add_event_mark (event, begin_time, GDK_PROFILER_CURRENT_TIME); add_event_mark (event, begin_time, GDK_PROFILER_CURRENT_TIME);

View File

@ -118,6 +118,9 @@ void gdk_surface_beep (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
void gdk_surface_queue_render (GdkSurface *surface); void gdk_surface_queue_render (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gdk_surface_request_layout (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GdkFrameClock* gdk_surface_get_frame_clock (GdkSurface *surface); GdkFrameClock* gdk_surface_get_frame_clock (GdkSurface *surface);
@ -125,13 +128,6 @@ GDK_AVAILABLE_IN_ALL
void gdk_surface_set_opaque_region (GdkSurface *surface, void gdk_surface_set_opaque_region (GdkSurface *surface,
cairo_region_t *region); cairo_region_t *region);
GDK_AVAILABLE_IN_ALL
void gdk_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GdkCairoContext *gdk_surface_create_cairo_context(GdkSurface *surface); GdkCairoContext *gdk_surface_create_cairo_context(GdkSurface *surface);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL

View File

@ -44,6 +44,10 @@ struct _GdkSurface
GdkSurface *parent; /* for popups */ GdkSurface *parent; /* for popups */
GList *children; /* popups */ GList *children; /* popups */
guint set_is_mapped_source_id;
gboolean pending_is_mapped;
gboolean is_mapped;
gpointer widget; gpointer widget;
int x; int x;
@ -53,13 +57,14 @@ struct _GdkSurface
cairo_region_t *update_area; cairo_region_t *update_area;
guint update_freeze_count; guint update_freeze_count;
gboolean pending_schedule_update; GdkFrameClockPhase pending_phases;
/* This is the update_area that was in effect when the current expose /* This is the update_area that was in effect when the current expose
started. It may be smaller than the expose area if we'e painting started. It may be smaller than the expose area if we'e painting
more than we have to, but it represents the "true" damage. */ more than we have to, but it represents the "true" damage. */
cairo_region_t *active_update_area; cairo_region_t *active_update_area;
GdkToplevelState old_state; GdkToplevelState pending_set_flags;
GdkToplevelState pending_unset_flags;
GdkToplevelState state; GdkToplevelState state;
guint8 resize_count; guint8 resize_count;
@ -83,10 +88,6 @@ struct _GdkSurface
guint update_and_descendants_freeze_count; guint update_and_descendants_freeze_count;
int width, height; int width, height;
int shadow_top;
int shadow_left;
int shadow_right;
int shadow_bottom;
GdkCursor *cursor; GdkCursor *cursor;
GHashTable *device_cursor; GHashTable *device_cursor;
@ -160,25 +161,24 @@ struct _GdkSurfaceClass
void (* set_opaque_region) (GdkSurface *surface, void (* set_opaque_region) (GdkSurface *surface,
cairo_region_t *region); cairo_region_t *region);
void (* set_shadow_width) (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
GdkGLContext *(*create_gl_context) (GdkSurface *surface, GdkGLContext *(*create_gl_context) (GdkSurface *surface,
gboolean attached, gboolean attached,
GdkGLContext *share, GdkGLContext *share,
GError **error); GError **error);
void (* request_layout) (GdkSurface *surface);
gboolean (* compute_size) (GdkSurface *surface);
}; };
#define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed) #define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed)
#define GDK_SURFACE_IS_MAPPED(surface) (((surface)->state & GDK_TOPLEVEL_STATE_WITHDRAWN) == 0) #define GDK_SURFACE_IS_MAPPED(surface) ((surface)->pending_is_mapped)
void gdk_surface_set_state (GdkSurface *surface, void gdk_surface_set_state (GdkSurface *surface,
GdkToplevelState new_state); GdkToplevelState new_state);
void gdk_surface_set_is_mapped (GdkSurface *surface,
gboolean is_mapped);
GdkMonitor * gdk_surface_get_layout_monitor (GdkSurface *surface, GdkMonitor * gdk_surface_get_layout_monitor (GdkSurface *surface,
GdkPopupLayout *layout, GdkPopupLayout *layout,
void (*get_bounds) (GdkMonitor *monitor, void (*get_bounds) (GdkMonitor *monitor,
@ -187,6 +187,10 @@ GdkMonitor * gdk_surface_get_layout_monitor (GdkSurface *surface,
void gdk_surface_layout_popup_helper (GdkSurface *surface, void gdk_surface_layout_popup_helper (GdkSurface *surface,
int width, int width,
int height, int height,
int shadow_left,
int shadow_right,
int shadow_top,
int shadow_bottom,
GdkMonitor *monitor, GdkMonitor *monitor,
GdkRectangle *bounds, GdkRectangle *bounds,
GdkPopupLayout *layout, GdkPopupLayout *layout,
@ -326,9 +330,22 @@ void gdk_surface_constrain_size (GdkGeometry *geometry,
int *new_width, int *new_width,
int *new_height); int *new_height);
void gdk_surface_queue_state_change (GdkSurface *surface,
GdkToplevelState unset_flags,
GdkToplevelState set_flags);
void gdk_surface_apply_state_change (GdkSurface *surface);
void gdk_surface_emit_size_changed (GdkSurface *surface,
int width,
int height);
void gdk_surface_request_compute_size (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
void gdk_surface_request_motion (GdkSurface *surface); void gdk_surface_request_motion (GdkSurface *surface);
G_END_DECLS G_END_DECLS
#endif /* __GDK_SURFACE_PRIVATE_H__ */ #endif /* __GDK_SURFACE_PRIVATE_H__ */

View File

@ -51,11 +51,10 @@ enum
static guint signals[N_SIGNALS] = { 0 }; static guint signals[N_SIGNALS] = { 0 };
static gboolean static void
gdk_toplevel_default_present (GdkToplevel *toplevel, gdk_toplevel_default_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout) GdkToplevelLayout *layout)
{ {
return FALSE;
} }
static gboolean static gboolean
@ -124,7 +123,7 @@ gdk_toplevel_default_init (GdkToplevelInterface *iface)
g_param_spec_flags ("state", g_param_spec_flags ("state",
P_("State"), P_("State"),
P_("State"), P_("State"),
GDK_TYPE_TOPLEVEL_STATE, GDK_TOPLEVEL_STATE_WITHDRAWN, GDK_TYPE_TOPLEVEL_STATE, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_interface_install_property (iface, g_object_interface_install_property (iface,
g_param_spec_string ("title", g_param_spec_string ("title",
@ -239,18 +238,17 @@ gdk_toplevel_install_properties (GObjectClass *object_class,
* compute the preferred size of the toplevel surface. See * compute the preferred size of the toplevel surface. See
* #GdkToplevel::compute-size for details. * #GdkToplevel::compute-size for details.
* *
* Presenting may fail. * Presenting is asynchronous and the specified layout parameters are not
* * guaranteed to be respected.
* Returns: %FALSE if @toplevel failed to be presented, otherwise %TRUE.
*/ */
gboolean void
gdk_toplevel_present (GdkToplevel *toplevel, gdk_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout) GdkToplevelLayout *layout)
{ {
g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE); g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
g_return_val_if_fail (layout != NULL, FALSE); g_return_if_fail (layout != NULL);
return GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout); GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout);
} }
/** /**

View File

@ -71,7 +71,6 @@ typedef enum
/** /**
* GdkToplevelState: * GdkToplevelState:
* @GDK_TOPLEVEL_STATE_WITHDRAWN: the surface is not shown
* @GDK_TOPLEVEL_STATE_MINIMIZED: the surface is minimized * @GDK_TOPLEVEL_STATE_MINIMIZED: the surface is minimized
* @GDK_TOPLEVEL_STATE_MAXIMIZED: the surface is maximized * @GDK_TOPLEVEL_STATE_MAXIMIZED: the surface is maximized
* @GDK_TOPLEVEL_STATE_STICKY: the surface is sticky * @GDK_TOPLEVEL_STATE_STICKY: the surface is sticky
@ -98,23 +97,22 @@ typedef enum
*/ */
typedef enum typedef enum
{ {
GDK_TOPLEVEL_STATE_WITHDRAWN = 1 << 0, GDK_TOPLEVEL_STATE_MINIMIZED = 1 << 0,
GDK_TOPLEVEL_STATE_MINIMIZED = 1 << 1, GDK_TOPLEVEL_STATE_MAXIMIZED = 1 << 1,
GDK_TOPLEVEL_STATE_MAXIMIZED = 1 << 2, GDK_TOPLEVEL_STATE_STICKY = 1 << 2,
GDK_TOPLEVEL_STATE_STICKY = 1 << 3, GDK_TOPLEVEL_STATE_FULLSCREEN = 1 << 3,
GDK_TOPLEVEL_STATE_FULLSCREEN = 1 << 4, GDK_TOPLEVEL_STATE_ABOVE = 1 << 4,
GDK_TOPLEVEL_STATE_ABOVE = 1 << 5, GDK_TOPLEVEL_STATE_BELOW = 1 << 5,
GDK_TOPLEVEL_STATE_BELOW = 1 << 6, GDK_TOPLEVEL_STATE_FOCUSED = 1 << 6,
GDK_TOPLEVEL_STATE_FOCUSED = 1 << 7, GDK_TOPLEVEL_STATE_TILED = 1 << 7,
GDK_TOPLEVEL_STATE_TILED = 1 << 8, GDK_TOPLEVEL_STATE_TOP_TILED = 1 << 8,
GDK_TOPLEVEL_STATE_TOP_TILED = 1 << 9, GDK_TOPLEVEL_STATE_TOP_RESIZABLE = 1 << 9,
GDK_TOPLEVEL_STATE_TOP_RESIZABLE = 1 << 10, GDK_TOPLEVEL_STATE_RIGHT_TILED = 1 << 10,
GDK_TOPLEVEL_STATE_RIGHT_TILED = 1 << 11, GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE = 1 << 11,
GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE = 1 << 12, GDK_TOPLEVEL_STATE_BOTTOM_TILED = 1 << 12,
GDK_TOPLEVEL_STATE_BOTTOM_TILED = 1 << 13, GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE = 1 << 13,
GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE = 1 << 14, GDK_TOPLEVEL_STATE_LEFT_TILED = 1 << 14,
GDK_TOPLEVEL_STATE_LEFT_TILED = 1 << 15, GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 15
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 16
} GdkToplevelState; } GdkToplevelState;
@ -129,7 +127,7 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_INTERFACE (GdkToplevel, gdk_toplevel, GDK, TOPLEVEL, GObject) G_DECLARE_INTERFACE (GdkToplevel, gdk_toplevel, GDK, TOPLEVEL, GObject)
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
gboolean gdk_toplevel_present (GdkToplevel *toplevel, void gdk_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout); GdkToplevelLayout *layout);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL

View File

@ -13,7 +13,7 @@ struct _GdkToplevelInterface
{ {
GTypeInterface g_iface; GTypeInterface g_iface;
gboolean (* present) (GdkToplevel *toplevel, void (* present) (GdkToplevel *toplevel,
GdkToplevelLayout *layout); GdkToplevelLayout *layout);
gboolean (* minimize) (GdkToplevel *toplevel); gboolean (* minimize) (GdkToplevel *toplevel);
gboolean (* lower) (GdkToplevel *toplevel); gboolean (* lower) (GdkToplevel *toplevel);

View File

@ -118,18 +118,53 @@ gdk_toplevel_size_set_min_size (GdkToplevelSize *size,
size->min_height = min_height; size->min_height = min_height;
} }
/**
* gdk_toplevel_size_set_shadow_width:
* @size: a #GdkToplevelSize
* @left: width of the left part of the shadow
* @right: width of the right part of the shadow
* @top: height of the top part of the shadow
* @bottom: height of the bottom part of the shadow
*
* 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.
*/
void
gdk_toplevel_size_set_shadow_width (GdkToplevelSize *size,
int left,
int right,
int top,
int bottom)
{
size->shadow.is_valid = TRUE;
size->shadow.left = left;
size->shadow.right = right;
size->shadow.top = top;
size->shadow.bottom = bottom;
}
void void
gdk_toplevel_size_validate (GdkToplevelSize *size) gdk_toplevel_size_validate (GdkToplevelSize *size)
{ {
int geometry_width, geometry_height;
if (size->min_width > size->bounds_width || if (size->min_width > size->bounds_width ||
size->min_height > size->bounds_height) size->min_height > size->bounds_height)
g_warning ("GdkToplevelSize: min_size (%d, %d) exceeds bounds (%d, %d)", g_warning ("GdkToplevelSize: min_size (%d, %d) exceeds bounds (%d, %d)",
size->min_width, size->min_height, size->min_width, size->min_height,
size->bounds_width, size->bounds_height); size->bounds_width, size->bounds_height);
if (size->width > size->bounds_width || geometry_width = size->width;
size->height > size->bounds_height) geometry_height = size->height;
g_warning ("GdkToplevelSize: size (%d, %d) exceeds bounds (%d, %d)", if (size->shadow.is_valid)
{
geometry_width -= size->shadow.left + size->shadow.right;
geometry_height -= size->shadow.top + size->shadow.bottom;
}
if (geometry_width > size->bounds_width ||
geometry_height > size->bounds_height)
g_warning ("GdkToplevelSize: geometry size (%d, %d) exceeds bounds (%d, %d)",
size->width, size->height, size->width, size->height,
size->bounds_width, size->bounds_height); size->bounds_width, size->bounds_height);

View File

@ -54,6 +54,13 @@ void gdk_toplevel_size_set_min_size (GdkToplevelSize *
int min_width, int min_width,
int min_height); int min_height);
GDK_AVAILABLE_IN_ALL
void gdk_toplevel_size_set_shadow_width (GdkToplevelSize *size,
int left,
int right,
int top,
int bottom);
G_END_DECLS G_END_DECLS
#endif /* __GDK_TOPLEVEL_SIZE_H__ */ #endif /* __GDK_TOPLEVEL_SIZE_H__ */

View File

@ -30,6 +30,14 @@ struct _GdkToplevelSize
int height; int height;
int min_width; int min_width;
int min_height; int min_height;
struct {
gboolean is_valid;
int left;
int right;
int top;
int bottom;
} shadow;
}; };
void gdk_toplevel_size_init (GdkToplevelSize *size, void gdk_toplevel_size_init (GdkToplevelSize *size,

View File

@ -256,13 +256,7 @@
_gdk_surface_update_size (surface); _gdk_surface_update_size (surface);
/* Synthesize a configure event */ gdk_surface_request_layout (surface);
event = gdk_configure_event_new (surface,
content_rect.size.width,
content_rect.size.height);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event,
_gdk_display_get_next_serial (display));
_gdk_macos_surface_reposition_children (gdk_surface); _gdk_macos_surface_reposition_children (gdk_surface);

View File

@ -69,6 +69,10 @@ gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
gdk_surface_layout_popup_helper (GDK_SURFACE (self), gdk_surface_layout_popup_helper (GDK_SURFACE (self),
width, width,
height, height,
self->parent_instance.shadow_left,
self->parent_instance.shadow_right,
self->parent_instance.shadow_top,
self->parent_instance.shadow_bottom,
monitor, monitor,
&bounds, &bounds,
self->layout, self->layout,

View File

@ -125,6 +125,11 @@ void _gdk_macos_surface_set_opacity (GdkMacosSurface
void _gdk_macos_surface_get_root_coords (GdkMacosSurface *self, void _gdk_macos_surface_get_root_coords (GdkMacosSurface *self,
int *x, int *x,
int *y); int *y);
void _gdk_macos_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
G_END_DECLS G_END_DECLS

View File

@ -85,7 +85,7 @@ _gdk_macos_surface_reposition_children (GdkMacosSurface *self)
} }
if (GDK_IS_POPUP (self) && self->did_initial_present) if (GDK_IS_POPUP (self) && self->did_initial_present)
g_signal_emit_by_name (self, "popup-layout-changed"); gdk_surface_request_layout (GDK_SURFACE (self));
} }
static void static void
@ -139,7 +139,7 @@ gdk_macos_surface_get_scale_factor (GdkSurface *surface)
return [self->window backingScaleFactor]; return [self->window backingScaleFactor];
} }
static void void
gdk_macos_surface_set_shadow_width (GdkSurface *surface, gdk_macos_surface_set_shadow_width (GdkSurface *surface,
int left, int left,
int right, int right,
@ -491,7 +491,6 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
surface_class->hide = gdk_macos_surface_hide; surface_class->hide = gdk_macos_surface_hide;
surface_class->set_input_region = gdk_macos_surface_set_input_region; surface_class->set_input_region = gdk_macos_surface_set_input_region;
surface_class->set_opaque_region = gdk_macos_surface_set_opaque_region; surface_class->set_opaque_region = gdk_macos_surface_set_opaque_region;
surface_class->set_shadow_width = gdk_macos_surface_set_shadow_width;
properties [PROP_NATIVE] = properties [PROP_NATIVE] =
g_param_spec_pointer ("native", g_param_spec_pointer ("native",
@ -763,7 +762,7 @@ _gdk_macos_surface_show (GdkMacosSurface *self)
was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)); was_mapped = GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
if (!was_mapped) if (!was_mapped)
gdk_synthesize_surface_state (GDK_SURFACE (self), GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (GDK_SURFACE (self), TRUE);
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display)); _gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display));

View File

@ -155,6 +155,15 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
if (style_mask != [nswindow styleMask]) if (style_mask != [nswindow styleMask])
[nswindow setStyleMask:style_mask]; [nswindow setStyleMask:style_mask];
if (size.shadow.is_valid)
{
_gdk_macos_surface_set_shadow_width (surface,
size.shadow.left,
size.shadow.right,
size.shadow.top,
size.shadow.bottom);
}
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask); _gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height); gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height); _gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);

View File

@ -4502,7 +4502,7 @@ gdk_wayland_seat_grab (GdkSeat *seat,
if (prepare_func) if (prepare_func)
(prepare_func) (seat, surface, prepare_func_data); (prepare_func) (seat, surface, prepare_func_data);
if (!gdk_surface_get_mapped (surface)) if (!gdk_wayland_surface_has_surface (surface))
{ {
gdk_wayland_seat_set_grab_surface (wayland_seat, NULL); gdk_wayland_seat_set_grab_surface (wayland_seat, NULL);
return GDK_GRAB_NOT_VIEWABLE; return GDK_GRAB_NOT_VIEWABLE;

View File

@ -96,6 +96,7 @@ void gdk_wayland_surface_sync (GdkSurface *surface);
void gdk_wayland_surface_commit (GdkSurface *surface); void gdk_wayland_surface_commit (GdkSurface *surface);
void gdk_wayland_surface_notify_committed (GdkSurface *surface); void gdk_wayland_surface_notify_committed (GdkSurface *surface);
void gdk_wayland_surface_request_frame (GdkSurface *surface); void gdk_wayland_surface_request_frame (GdkSurface *surface);
gboolean gdk_wayland_surface_has_surface (GdkSurface *surface);
void gdk_wayland_surface_attach_image (GdkSurface *surface, void gdk_wayland_surface_attach_image (GdkSurface *surface,
cairo_surface_t *cairo_surface, cairo_surface_t *cairo_surface,
const cairo_region_t *damage); const cairo_region_t *damage);

View File

@ -122,11 +122,11 @@ struct _GdkWaylandSurface
gint64 pending_frame_counter; gint64 pending_frame_counter;
guint32 scale; guint32 scale;
int margin_left; int shadow_left;
int margin_right; int shadow_right;
int margin_top; int shadow_top;
int margin_bottom; int shadow_bottom;
gboolean margin_dirty; gboolean shadow_dirty;
struct wl_output *initial_fullscreen_output; struct wl_output *initial_fullscreen_output;
@ -162,6 +162,7 @@ struct _GdkWaylandSurface
int width; int width;
int height; int height;
GdkToplevelState state; GdkToplevelState state;
gboolean is_resizing;
} toplevel; } toplevel;
struct { struct {
@ -179,6 +180,25 @@ struct _GdkWaylandSurface
gboolean is_dirty; gboolean is_dirty;
} pending; } pending;
struct {
GdkToplevelState unset_flags;
GdkToplevelState set_flags;
} initial_state;
struct {
struct {
gboolean should_constrain;
gboolean size_is_fixed;
} toplevel;
struct {
int x;
int y;
} popup;
int configured_width;
int configured_height;
gboolean surface_geometry_dirty;
} next_layout;
uint32_t last_configure_serial; uint32_t last_configure_serial;
int state_freeze_count; int state_freeze_count;
@ -264,12 +284,17 @@ static void gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int height, int height,
int scale); int scale);
static void gdk_wayland_surface_resize (GdkSurface *surface,
int width,
int height,
int scale);
static void gdk_wayland_surface_configure (GdkSurface *surface); static void gdk_wayland_surface_configure (GdkSurface *surface);
static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl); static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl);
static void maybe_set_gtk_surface_modal (GdkSurface *surface); static void maybe_set_gtk_surface_modal (GdkSurface *surface);
static void gdk_wayland_surface_sync_margin (GdkSurface *surface); static void gdk_wayland_surface_sync_shadow (GdkSurface *surface);
static void gdk_wayland_surface_sync_input_region (GdkSurface *surface); static void gdk_wayland_surface_sync_input_region (GdkSurface *surface);
static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface); static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface);
@ -290,6 +315,8 @@ static void update_popup_layout_state (GdkSurface *surface,
static gboolean gdk_wayland_surface_is_exported (GdkWaylandSurface *impl); static gboolean gdk_wayland_surface_is_exported (GdkWaylandSurface *impl);
static void configure_toplevel_geometry (GdkSurface *surface);
static void static void
gdk_wayland_surface_init (GdkWaylandSurface *impl) gdk_wayland_surface_init (GdkWaylandSurface *impl)
{ {
@ -336,8 +363,11 @@ _gdk_wayland_surface_save_size (GdkSurface *surface)
GDK_TOPLEVEL_STATE_TILED)) GDK_TOPLEVEL_STATE_TILED))
return; return;
impl->saved_width = surface->width - impl->margin_left - impl->margin_right; if (surface->width <= 1 || surface->height <= 1)
impl->saved_height = surface->height - impl->margin_top - impl->margin_bottom; return;
impl->saved_width = surface->width - impl->shadow_left - impl->shadow_right;
impl->saved_height = surface->height - impl->shadow_top - impl->shadow_bottom;
} }
static void static void
@ -582,6 +612,59 @@ on_frame_clock_before_paint (GdkFrameClock *clock,
*/ */
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval; timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
} }
gdk_surface_apply_state_change (surface);
}
static void
configure_popup_geometry (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gdk_wayland_surface_move_resize (surface,
impl->next_layout.popup.x,
impl->next_layout.popup.y,
impl->next_layout.configured_width,
impl->next_layout.configured_height);
}
static void
configure_drag_surface_geometry (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gdk_wayland_surface_resize (surface,
impl->next_layout.configured_width,
impl->next_layout.configured_height,
impl->scale);
}
static gboolean
gdk_wayland_surface_compute_size (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (impl->next_layout.surface_geometry_dirty)
{
if (GDK_IS_TOPLEVEL (impl))
configure_toplevel_geometry (surface);
else if (GDK_IS_POPUP (impl))
configure_popup_geometry (surface);
else if (GDK_IS_DRAG_SURFACE (impl))
configure_drag_surface_geometry (surface);
impl->next_layout.surface_geometry_dirty = FALSE;
}
return FALSE;
}
static void
gdk_wayland_surface_request_layout (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
impl->next_layout.surface_geometry_dirty = TRUE;
} }
void void
@ -603,6 +686,14 @@ gdk_wayland_surface_request_frame (GdkSurface *surface)
impl->awaiting_frame = TRUE; impl->awaiting_frame = TRUE;
} }
gboolean
gdk_wayland_surface_has_surface (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
return !!impl->display_server.wl_surface;
}
void void
gdk_wayland_surface_commit (GdkSurface *surface) gdk_wayland_surface_commit (GdkSurface *surface)
{ {
@ -801,7 +892,7 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
void void
gdk_wayland_surface_sync (GdkSurface *surface) gdk_wayland_surface_sync (GdkSurface *surface)
{ {
gdk_wayland_surface_sync_margin (surface); gdk_wayland_surface_sync_shadow (surface);
gdk_wayland_surface_sync_opaque_region (surface); gdk_wayland_surface_sync_opaque_region (surface);
gdk_wayland_surface_sync_input_region (surface); gdk_wayland_surface_sync_input_region (surface);
} }
@ -910,16 +1001,6 @@ gdk_wayland_surface_resize (GdkSurface *surface,
{ {
gdk_wayland_surface_update_size (surface, width, height, scale); gdk_wayland_surface_update_size (surface, width, height, scale);
_gdk_surface_update_size (surface); _gdk_surface_update_size (surface);
if (is_realized_shell_surface (GDK_WAYLAND_SURFACE (surface)))
{
GdkDisplay *display;
GdkEvent *event;
event = gdk_configure_event_new (surface, width, height);
display = gdk_surface_get_display (surface);
_gdk_wayland_display_deliver_event (display, event);
}
} }
static void gdk_wayland_surface_show (GdkSurface *surface, static void gdk_wayland_surface_show (GdkSurface *surface,
@ -1069,10 +1150,10 @@ gdk_wayland_surface_get_window_geometry (GdkSurface *surface,
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
*geometry = (GdkRectangle) { *geometry = (GdkRectangle) {
.x = impl->margin_left, .x = impl->shadow_left,
.y = impl->margin_top, .y = impl->shadow_top,
.width = surface->width - (impl->margin_left + impl->margin_right), .width = surface->width - (impl->shadow_left + impl->shadow_right),
.height = surface->height - (impl->margin_top + impl->margin_bottom) .height = surface->height - (impl->shadow_top + impl->shadow_bottom)
}; };
} }
@ -1081,7 +1162,7 @@ static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl,
GdkSurfaceHints geom_mask); GdkSurfaceHints geom_mask);
static void static void
gdk_wayland_surface_sync_margin (GdkSurface *surface) gdk_wayland_surface_sync_shadow (GdkSurface *surface)
{ {
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland = GdkWaylandDisplay *display_wayland =
@ -1255,7 +1336,7 @@ gdk_wayland_surface_create_surface (GdkSurface *surface)
} }
static void static void
configure_surface_geometry (GdkSurface *surface) configure_toplevel_geometry (GdkSurface *surface)
{ {
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface); GdkDisplay *display = gdk_surface_get_display (surface);
@ -1263,7 +1344,6 @@ configure_surface_geometry (GdkSurface *surface)
GdkRectangle monitor_geometry; GdkRectangle monitor_geometry;
int bounds_width, bounds_height; int bounds_width, bounds_height;
GdkToplevelSize size; GdkToplevelSize size;
int width, height;
GdkToplevelLayout *layout; GdkToplevelLayout *layout;
GdkGeometry geometry; GdkGeometry geometry;
GdkSurfaceHints mask; GdkSurfaceHints mask;
@ -1276,10 +1356,8 @@ configure_surface_geometry (GdkSurface *surface)
gdk_toplevel_size_init (&size, bounds_width, bounds_height); gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size); gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
width = size.width; g_warn_if_fail (size.width > 0);
height = size.height; g_warn_if_fail (size.height > 0);
g_warn_if_fail (width > 0);
g_warn_if_fail (height > 0);
layout = impl->toplevel.layout; layout = impl->toplevel.layout;
if (gdk_toplevel_layout_get_resizable (layout)) if (gdk_toplevel_layout_get_resizable (layout))
@ -1290,13 +1368,71 @@ configure_surface_geometry (GdkSurface *surface)
} }
else else
{ {
geometry.max_width = geometry.min_width = width; geometry.max_width = geometry.min_width = size.width;
geometry.max_height = geometry.min_height = height; geometry.max_height = geometry.min_height = size.height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
} }
gdk_wayland_surface_set_geometry_hints (impl, &geometry, mask); gdk_wayland_surface_set_geometry_hints (impl, &geometry, mask);
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
gdk_wayland_surface_resize (surface, width, height, impl->scale); if (size.shadow.is_valid)
{
impl->shadow_left = size.shadow.left;
impl->shadow_right = size.shadow.right;
impl->shadow_top = size.shadow.top;
impl->shadow_bottom = size.shadow.bottom;
}
if (impl->next_layout.configured_width > 0 &&
impl->next_layout.configured_height > 0)
{
int width, height;
width = impl->next_layout.configured_width +
impl->shadow_left + impl->shadow_right;
height = impl->next_layout.configured_height +
impl->shadow_top + impl->shadow_bottom;
if (impl->next_layout.toplevel.should_constrain)
{
gdk_surface_constrain_size (&impl->geometry_hints,
impl->geometry_mask,
width, height,
&width, &height);
}
gdk_wayland_surface_resize (surface, width, height, impl->scale);
if (!impl->next_layout.toplevel.size_is_fixed)
{
impl->next_layout.toplevel.should_constrain = FALSE;
impl->next_layout.configured_width = 0;
impl->next_layout.configured_height = 0;
}
}
else
{
int width, height;
width = size.width;
height = size.height;
gdk_surface_constrain_size (&geometry, mask,
width, height,
&width, &height);
gdk_wayland_surface_resize (surface, width, height, impl->scale);
}
}
static void
synthesize_initial_surface_state (GdkSurface *surface,
GdkToplevelState unset_flags,
GdkToplevelState set_flags)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
impl->initial_state.unset_flags |= unset_flags;
impl->initial_state.set_flags &= ~unset_flags;
impl->initial_state.set_flags |= set_flags;
impl->initial_state.unset_flags &= ~set_flags;
} }
static void static void
@ -1307,16 +1443,21 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkToplevelState new_state; GdkToplevelState new_state;
int width, height; int width, height;
gboolean is_resizing;
gboolean fixed_size; gboolean fixed_size;
gboolean saved_size; gboolean saved_size;
new_state = impl->pending.toplevel.state; new_state = impl->pending.toplevel.state;
impl->pending.toplevel.state = 0; impl->pending.toplevel.state = 0;
is_resizing = impl->pending.toplevel.is_resizing;
impl->pending.toplevel.is_resizing = FALSE;
fixed_size = fixed_size =
new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED | new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_FULLSCREEN | GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_TILED); GDK_TOPLEVEL_STATE_TILED) ||
is_resizing;
width = impl->pending.toplevel.width; width = impl->pending.toplevel.width;
height = impl->pending.toplevel.height; height = impl->pending.toplevel.height;
@ -1338,34 +1479,37 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
if (width > 0 && height > 0) if (width > 0 && height > 0)
{ {
GdkSurfaceHints geometry_mask = impl->geometry_mask;
if (!saved_size) if (!saved_size)
{ {
/* Do not reapply constrains if we are restoring original size */ impl->next_layout.toplevel.should_constrain = TRUE;
gdk_surface_constrain_size (&impl->geometry_hints,
geometry_mask,
width + impl->margin_left + impl->margin_right,
height + impl->margin_top + impl->margin_bottom,
&width,
&height);
/* Save size for next time we get 0x0 */ /* Save size for next time we get 0x0 */
_gdk_wayland_surface_save_size (surface); _gdk_wayland_surface_save_size (surface);
} }
else if (is_resizing)
{
impl->next_layout.toplevel.should_constrain = TRUE;
}
else else
{ {
width += impl->margin_left + impl->margin_right; impl->next_layout.toplevel.should_constrain = FALSE;
height += impl->margin_top + impl->margin_bottom;
} }
gdk_wayland_surface_resize (surface, width, height, impl->scale); impl->next_layout.toplevel.size_is_fixed = fixed_size;
impl->next_layout.configured_width = width;
impl->next_layout.configured_height = height;
} }
else else
{ {
configure_surface_geometry (surface); impl->next_layout.toplevel.should_constrain = FALSE;
impl->next_layout.toplevel.size_is_fixed = FALSE;
impl->next_layout.configured_width = 0;
impl->next_layout.configured_height = 0;
} }
impl->next_layout.surface_geometry_dirty = TRUE;
gdk_surface_request_layout (surface);
GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS,
g_message ("configure, surface %p %dx%d,%s%s%s%s", g_message ("configure, surface %p %dx%d,%s%s%s%s",
surface, width, height, surface, width, height,
@ -1374,7 +1518,7 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
(new_state & GDK_TOPLEVEL_STATE_FOCUSED) ? " focused" : "", (new_state & GDK_TOPLEVEL_STATE_FOCUSED) ? " focused" : "",
(new_state & GDK_TOPLEVEL_STATE_TILED) ? " tiled" : "")); (new_state & GDK_TOPLEVEL_STATE_TILED) ? " tiled" : ""));
gdk_surface_set_state (surface, new_state); gdk_surface_queue_state_change (surface, ~0 & ~new_state, new_state);
switch (display_wayland->shell_variant) switch (display_wayland->shell_variant)
{ {
@ -1395,6 +1539,7 @@ static void
gdk_wayland_surface_configure_popup (GdkSurface *surface) gdk_wayland_surface_configure_popup (GdkSurface *surface)
{ {
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (surface->parent);
int x, y, width, height; int x, y, width, height;
if (impl->display_server.xdg_popup) if (impl->display_server.xdg_popup)
@ -1434,18 +1579,30 @@ gdk_wayland_surface_configure_popup (GdkSurface *surface)
width = impl->pending.popup.width; width = impl->pending.popup.width;
height = impl->pending.popup.height; height = impl->pending.popup.height;
gdk_wayland_surface_resize (surface, width, height, impl->scale); x += parent_impl->shadow_left;
y += parent_impl->shadow_top;
update_popup_layout_state (surface, update_popup_layout_state (surface,
x, y, x, y,
width, height, width, height,
impl->popup.layout); impl->popup.layout);
if (!impl->pending.popup.has_repositioned_token && impl->next_layout.popup.x = x;
!impl->pending.is_initial_configure) impl->next_layout.popup.y = y;
g_signal_emit_by_name (surface, "popup-layout-changed"); impl->next_layout.configured_width = width;
impl->next_layout.configured_height = height;
impl->next_layout.surface_geometry_dirty = TRUE;
gdk_surface_request_layout (surface);
}
gdk_surface_invalidate_rect (surface, NULL); static void
maybe_notify_mapped (GdkSurface *surface)
{
if (surface->destroyed)
return;
if (!GDK_SURFACE_IS_MAPPED (surface))
gdk_surface_set_is_mapped (surface, TRUE);
} }
static void static void
@ -1458,6 +1615,7 @@ gdk_wayland_surface_configure (GdkSurface *surface)
gdk_surface_thaw_updates (surface); gdk_surface_thaw_updates (surface);
impl->initial_configure_received = TRUE; impl->initial_configure_received = TRUE;
impl->pending.is_initial_configure = TRUE; impl->pending.is_initial_configure = TRUE;
maybe_notify_mapped (surface);
} }
impl->has_uncommitted_ack_configure = TRUE; impl->has_uncommitted_ack_configure = TRUE;
@ -1539,9 +1697,12 @@ xdg_toplevel_configure (void *data,
struct wl_array *states) struct wl_array *states)
{ {
GdkSurface *surface = GDK_SURFACE (data); GdkSurface *surface = GDK_SURFACE (data);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
uint32_t *p; uint32_t *p;
GdkToplevelState pending_state = 0; GdkToplevelState pending_state = 0;
impl->pending.toplevel.is_resizing = FALSE;
wl_array_for_each (p, states) wl_array_for_each (p, states)
{ {
uint32_t state = *p; uint32_t state = *p;
@ -1558,6 +1719,7 @@ xdg_toplevel_configure (void *data,
pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; pending_state |= GDK_TOPLEVEL_STATE_FOCUSED;
break; break;
case XDG_TOPLEVEL_STATE_RESIZING: case XDG_TOPLEVEL_STATE_RESIZING:
impl->pending.toplevel.is_resizing = TRUE;
break; break;
default: default:
/* Unknown state */ /* Unknown state */
@ -1628,9 +1790,12 @@ zxdg_toplevel_v6_configure (void *data,
struct wl_array *states) struct wl_array *states)
{ {
GdkSurface *surface = GDK_SURFACE (data); GdkSurface *surface = GDK_SURFACE (data);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
uint32_t *p; uint32_t *p;
GdkToplevelState pending_state = 0; GdkToplevelState pending_state = 0;
impl->pending.toplevel.is_resizing = FALSE;
wl_array_for_each (p, states) wl_array_for_each (p, states)
{ {
uint32_t state = *p; uint32_t state = *p;
@ -1647,6 +1812,7 @@ zxdg_toplevel_v6_configure (void *data,
pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; pending_state |= GDK_TOPLEVEL_STATE_FOCUSED;
break; break;
case ZXDG_TOPLEVEL_V6_STATE_RESIZING: case ZXDG_TOPLEVEL_V6_STATE_RESIZING:
impl->pending.toplevel.is_resizing = TRUE;
break; break;
default: default:
/* Unknown state */ /* Unknown state */
@ -1764,20 +1930,20 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
switch (display_wayland->shell_variant) switch (display_wayland->shell_variant)
{ {
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
if (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED)
xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel);
if (surface->state & GDK_TOPLEVEL_STATE_MINIMIZED) if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED)
xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel);
if (surface->state & GDK_TOPLEVEL_STATE_FULLSCREEN) if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN)
xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel,
impl->initial_fullscreen_output); impl->initial_fullscreen_output);
break; break;
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
if (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED)
zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6);
if (surface->state & GDK_TOPLEVEL_STATE_MINIMIZED) if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED)
zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6);
if (surface->state & GDK_TOPLEVEL_STATE_FULLSCREEN) if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN)
zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6,
impl->initial_fullscreen_output); impl->initial_fullscreen_output);
break; break;
@ -2098,9 +2264,9 @@ calculate_popup_rect (GdkSurface *surface,
int x = 0, y = 0; int x = 0, y = 0;
width = (impl->popup.unconstrained_width - width = (impl->popup.unconstrained_width -
(impl->margin_left + impl->margin_right)); (impl->shadow_left + impl->shadow_right));
height = (impl->popup.unconstrained_height - height = (impl->popup.unconstrained_height -
(impl->margin_top + impl->margin_bottom)); (impl->shadow_top + impl->shadow_bottom));
anchor_rect = *gdk_popup_layout_get_anchor_rect (layout); anchor_rect = *gdk_popup_layout_get_anchor_rect (layout);
gdk_popup_layout_get_offset (layout, &dx, &dy); gdk_popup_layout_get_offset (layout, &dx, &dy);
@ -2201,26 +2367,12 @@ update_popup_layout_state (GdkSurface *surface,
int height, int height,
GdkPopupLayout *layout) GdkPopupLayout *layout)
{ {
int surface_x, surface_y;
int surface_width, surface_height;
GdkRectangle best_rect; GdkRectangle best_rect;
GdkRectangle flipped_rect; GdkRectangle flipped_rect;
GdkGravity rect_anchor; GdkGravity rect_anchor;
GdkGravity surface_anchor; GdkGravity surface_anchor;
GdkAnchorHints anchor_hints; GdkAnchorHints anchor_hints;
x += surface->parent->shadow_left;
y += surface->parent->shadow_top;
surface_x = x;
surface_y = y;
surface_width = width + surface->shadow_left + surface->shadow_right;
surface_height = height + surface->shadow_top + surface->shadow_bottom;
gdk_wayland_surface_move_resize (surface,
surface_x, surface_y,
surface_width, surface_height);
rect_anchor = gdk_popup_layout_get_rect_anchor (layout); rect_anchor = gdk_popup_layout_get_rect_anchor (layout);
surface_anchor = gdk_popup_layout_get_surface_anchor (layout); surface_anchor = gdk_popup_layout_get_surface_anchor (layout);
anchor_hints = gdk_popup_layout_get_anchor_hints (layout); anchor_hints = gdk_popup_layout_get_anchor_hints (layout);
@ -2300,6 +2452,7 @@ create_dynamic_positioner (GdkSurface *surface,
{ {
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkSurface *parent = surface->parent; GdkSurface *parent = surface->parent;
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent);
GdkWaylandDisplay *display = GdkWaylandDisplay *display =
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkRectangle geometry; GdkRectangle geometry;
@ -2314,15 +2467,15 @@ create_dynamic_positioner (GdkSurface *surface,
GdkAnchorHints anchor_hints; GdkAnchorHints anchor_hints;
geometry = (GdkRectangle) { geometry = (GdkRectangle) {
.x = impl->margin_left, .x = impl->shadow_left,
.y = impl->margin_top, .y = impl->shadow_top,
.width = width - (impl->margin_left + impl->margin_right), .width = width - (impl->shadow_left + impl->shadow_right),
.height = height - (impl->margin_top + impl->margin_bottom), .height = height - (impl->shadow_top + impl->shadow_bottom),
}; };
anchor_rect = gdk_popup_layout_get_anchor_rect (layout); anchor_rect = gdk_popup_layout_get_anchor_rect (layout);
real_anchor_rect_x = anchor_rect->x - parent->shadow_left; real_anchor_rect_x = anchor_rect->x - parent_impl->shadow_left;
real_anchor_rect_y = anchor_rect->y - parent->shadow_top; real_anchor_rect_y = anchor_rect->y - parent_impl->shadow_top;
anchor_rect_width = MAX (anchor_rect->width, 1); anchor_rect_width = MAX (anchor_rect->width, 1);
anchor_rect_height = MAX (anchor_rect->height, 1); anchor_rect_height = MAX (anchor_rect->height, 1);
@ -2381,14 +2534,13 @@ create_dynamic_positioner (GdkSurface *surface,
xdg_positioner_get_version (positioner) >= xdg_positioner_get_version (positioner) >=
XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION) XDG_POSITIONER_SET_PARENT_CONFIGURE_SINCE_VERSION)
{ {
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent);
int parent_width; int parent_width;
int parent_height; int parent_height;
parent_width = parent->width - (parent_impl->margin_left + parent_width = parent->width - (parent_impl->shadow_left +
parent_impl->margin_right); parent_impl->shadow_right);
parent_height = parent->height - (parent_impl->margin_top + parent_height = parent->height - (parent_impl->shadow_top +
parent_impl->margin_bottom); parent_impl->shadow_bottom);
xdg_positioner_set_parent_size (positioner, xdg_positioner_set_parent_size (positioner,
parent_width, parent_width,
@ -2807,6 +2959,12 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
unset_transient_for_exported (surface); unset_transient_for_exported (surface);
impl->last_sent_window_geometry = (GdkRectangle) { 0 };
impl->last_sent_min_width = 0;
impl->last_sent_min_height = 0;
impl->last_sent_max_width = 0;
impl->last_sent_max_height = 0;
_gdk_wayland_surface_clear_saved_size (surface); _gdk_wayland_surface_clear_saved_size (surface);
impl->mapped = FALSE; impl->mapped = FALSE;
} }
@ -2982,8 +3140,6 @@ gdk_wayland_surface_map_popup (GdkSurface *surface,
impl->popup.unconstrained_width = width; impl->popup.unconstrained_width = width;
impl->popup.unconstrained_height = height; impl->popup.unconstrained_height = height;
impl->mapped = TRUE; impl->mapped = TRUE;
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
} }
static void static void
@ -3410,9 +3566,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl,
if (geom_mask & GDK_HINT_MIN_SIZE) if (geom_mask & GDK_HINT_MIN_SIZE)
{ {
min_width = MAX (0, (geometry->min_width - min_width = MAX (0, (geometry->min_width -
(impl->margin_left + impl->margin_right))); (impl->shadow_left + impl->shadow_right)));
min_height = MAX (0, (geometry->min_height - min_height = MAX (0, (geometry->min_height -
(impl->margin_top + impl->margin_bottom))); (impl->shadow_top + impl->shadow_bottom)));
} }
else else
{ {
@ -3423,9 +3579,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl,
if (geom_mask & GDK_HINT_MAX_SIZE) if (geom_mask & GDK_HINT_MAX_SIZE)
{ {
max_width = MAX (0, (geometry->max_width - max_width = MAX (0, (geometry->max_width -
(impl->margin_left + impl->margin_right))); (impl->shadow_left + impl->shadow_right)));
max_height = MAX (0, (geometry->max_height - max_height = MAX (0, (geometry->max_height -
(impl->margin_top + impl->margin_bottom))); (impl->shadow_top + impl->shadow_bottom)));
} }
else else
{ {
@ -3608,7 +3764,7 @@ gdk_wayland_surface_maximize (GdkSurface *surface)
} }
else else
{ {
gdk_synthesize_surface_state (surface, 0, GDK_TOPLEVEL_STATE_MAXIMIZED); synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_MAXIMIZED);
} }
} }
@ -3639,7 +3795,7 @@ gdk_wayland_surface_unmaximize (GdkSurface *surface)
} }
else else
{ {
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0); synthesize_initial_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
} }
} }
@ -3676,7 +3832,7 @@ gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface,
} }
else else
{ {
gdk_synthesize_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN);
impl->initial_fullscreen_output = output; impl->initial_fullscreen_output = output;
} }
} }
@ -3714,7 +3870,7 @@ gdk_wayland_surface_fullscreen (GdkSurface *surface)
} }
else else
{ {
gdk_synthesize_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN);
} }
} }
@ -3747,7 +3903,7 @@ gdk_wayland_surface_unfullscreen (GdkSurface *surface)
} }
else else
{ {
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_FULLSCREEN, 0); synthesize_initial_surface_state (surface, GDK_TOPLEVEL_STATE_FULLSCREEN, 0);
} }
} }
@ -3921,34 +4077,6 @@ gdk_wayland_surface_set_opaque_region (GdkSurface *surface,
impl->opaque_region_dirty = TRUE; impl->opaque_region_dirty = TRUE;
} }
static void
gdk_wayland_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
int new_width, new_height;
if (GDK_SURFACE_DESTROYED (surface))
return;
/* Reconfigure surface to keep the same surface geometry */
new_width = surface->width -
(impl->margin_left + impl->margin_right) + (left + right);
new_height = surface->height -
(impl->margin_top + impl->margin_bottom) + (top + bottom);
gdk_wayland_surface_maybe_resize (surface,
new_width, new_height,
impl->scale);
impl->margin_left = left;
impl->margin_right = right;
impl->margin_top = top;
impl->margin_bottom = bottom;
}
static gboolean static gboolean
gdk_wayland_surface_show_window_menu (GdkSurface *surface, gdk_wayland_surface_show_window_menu (GdkSurface *surface,
GdkEvent *event) GdkEvent *event)
@ -4033,8 +4161,9 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
impl_class->drag_begin = _gdk_wayland_surface_drag_begin; impl_class->drag_begin = _gdk_wayland_surface_drag_begin;
impl_class->get_scale_factor = gdk_wayland_surface_get_scale_factor; impl_class->get_scale_factor = gdk_wayland_surface_get_scale_factor;
impl_class->set_opaque_region = gdk_wayland_surface_set_opaque_region; impl_class->set_opaque_region = gdk_wayland_surface_set_opaque_region;
impl_class->set_shadow_width = gdk_wayland_surface_set_shadow_width;
impl_class->create_gl_context = gdk_wayland_surface_create_gl_context; impl_class->create_gl_context = gdk_wayland_surface_create_gl_context;
impl_class->request_layout = gdk_wayland_surface_request_layout;
impl_class->compute_size = gdk_wayland_surface_compute_size;
} }
void void
@ -4736,98 +4865,94 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
gdk_toplevel_install_properties (object_class, 1); gdk_toplevel_install_properties (object_class, 1);
} }
static void static gboolean
show_surface (GdkSurface *surface) did_maximize_layout_change (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{ {
gboolean was_mapped; GdkSurface *surface = GDK_SURFACE (toplevel);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (surface->destroyed) if (!impl->toplevel.layout)
return; return TRUE;
was_mapped = GDK_SURFACE_IS_MAPPED (surface); if (gdk_toplevel_layout_get_maximized (impl->toplevel.layout) !=
gdk_toplevel_layout_get_maximized (layout) ||
!!(surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) !=
gdk_toplevel_layout_get_maximized (layout))
return TRUE;
if (!was_mapped) return FALSE;
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
gdk_wayland_surface_show (surface, FALSE);
if (!was_mapped)
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 static gboolean
did_fullscreen_layout_change (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->toplevel.layout)
return TRUE;
if (gdk_toplevel_layout_get_fullscreen (impl->toplevel.layout) !=
gdk_toplevel_layout_get_fullscreen (layout) ||
!!(surface->state & GDK_TOPLEVEL_STATE_FULLSCREEN) !=
gdk_toplevel_layout_get_fullscreen (layout))
return TRUE;
if (gdk_toplevel_layout_get_fullscreen_monitor (impl->toplevel.layout) !=
gdk_toplevel_layout_get_fullscreen_monitor (layout))
return TRUE;
return FALSE;
}
static void
gdk_wayland_toplevel_present (GdkToplevel *toplevel, gdk_wayland_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout) GdkToplevelLayout *layout)
{ {
GdkSurface *surface = GDK_SURFACE (toplevel); GdkSurface *surface = GDK_SURFACE (toplevel);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland; gboolean pending_configure = FALSE;
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)) if (did_maximize_layout_change (toplevel, layout))
{ {
gdk_wayland_surface_maximize (surface); if (gdk_toplevel_layout_get_maximized (layout))
needs_reconfigure = FALSE; gdk_wayland_surface_maximize (surface);
}
else
{
gdk_wayland_surface_unmaximize (surface);
}
if (gdk_toplevel_layout_get_fullscreen (layout))
{
GdkMonitor *monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
if (monitor)
gdk_wayland_surface_fullscreen_on_monitor (surface, monitor);
else else
gdk_wayland_surface_fullscreen (surface); gdk_wayland_surface_unmaximize (surface);
needs_reconfigure = FALSE; pending_configure = TRUE;
}
if (did_fullscreen_layout_change (toplevel, layout))
{
if (gdk_toplevel_layout_get_fullscreen (layout))
{
GdkMonitor *monitor;
monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
if (monitor)
gdk_wayland_surface_fullscreen_on_monitor (surface, monitor);
else
gdk_wayland_surface_fullscreen (surface);
}
else
{
gdk_wayland_surface_unfullscreen (surface);
}
pending_configure = TRUE;
} }
else
gdk_wayland_surface_unfullscreen (surface);
g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref); g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref);
impl->toplevel.layout = gdk_toplevel_layout_copy (layout); impl->toplevel.layout = gdk_toplevel_layout_copy (layout);
show_surface (surface); gdk_wayland_surface_show (surface, FALSE);
display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); if (!pending_configure)
callback = wl_display_sync (display_wayland->wl_display); {
wl_proxy_set_queue ((struct wl_proxy *) callback, impl->event_queue); impl->next_layout.surface_geometry_dirty = TRUE;
wl_callback_add_listener (callback, gdk_surface_request_layout (surface);
&reconfigure_listener, }
&done);
while (is_realized_toplevel (impl) &&
(!impl->initial_configure_received || !done))
wl_display_dispatch_queue (display_wayland->wl_display, impl->event_queue);
wl_callback_destroy (callback);
if (needs_reconfigure &&
last_configure_serial == impl->last_configure_serial &&
!(surface->state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_TILED)))
configure_surface_geometry (surface);
return TRUE;
} }
static gboolean static gboolean
@ -4961,8 +5086,14 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
GdkSurface *surface = GDK_SURFACE (drag_surface); GdkSurface *surface = GDK_SURFACE (drag_surface);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gdk_wayland_surface_resize (surface, width, height, impl->scale); gdk_wayland_surface_show (surface, FALSE);
show_surface (surface);
impl->next_layout.configured_width = width;
impl->next_layout.configured_height = height;
impl->next_layout.surface_geometry_dirty = TRUE;
gdk_surface_request_layout (surface);
maybe_notify_mapped (surface);
return TRUE; return TRUE;
} }

View File

@ -562,7 +562,6 @@ event_mask_string (GdkEventMask mask)
BIT (VISIBILITY_NOTIFY); BIT (VISIBILITY_NOTIFY);
BIT (PROXIMITY_IN); BIT (PROXIMITY_IN);
BIT (PROXIMITY_OUT); BIT (PROXIMITY_OUT);
BIT (SUBSTRUCTURE);
BIT (SCROLL); BIT (SCROLL);
#undef BIT #undef BIT
@ -1278,35 +1277,6 @@ _gdk_win32_get_window_rect (GdkSurface *window,
return !impl->inhibit_configure; return !impl->inhibit_configure;
} }
void
_gdk_win32_do_emit_configure_event (GdkSurface *surface,
RECT rect)
{
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
impl->unscaled_width = rect.right - rect.left;
impl->unscaled_height = rect.bottom - rect.top;
surface->width = (impl->unscaled_width + impl->surface_scale - 1) / impl->surface_scale;
surface->height = (impl->unscaled_height + impl->surface_scale - 1) / impl->surface_scale;
surface->x = rect.left / impl->surface_scale;
surface->y = rect.top / impl->surface_scale;
_gdk_surface_update_size (surface);
g_signal_emit_by_name (surface, "size-changed", surface->width, surface->height);
}
void
_gdk_win32_emit_configure_event (GdkSurface *surface)
{
RECT rect;
if (!_gdk_win32_get_window_rect (surface, &rect))
return;
_gdk_win32_do_emit_configure_event (surface, rect);
}
cairo_region_t * cairo_region_t *
_gdk_win32_hrgn_to_region (HRGN hrgn, _gdk_win32_hrgn_to_region (HRGN hrgn,
guint scale) guint scale)
@ -2855,11 +2825,6 @@ gdk_event_translate (MSG *msg,
set_bits = 0; set_bits = 0;
unset_bits = 0; unset_bits = 0;
if (IsWindowVisible (msg->hwnd))
unset_bits |= GDK_TOPLEVEL_STATE_WITHDRAWN;
else
set_bits |= GDK_TOPLEVEL_STATE_WITHDRAWN;
if (IsIconic (msg->hwnd)) if (IsIconic (msg->hwnd))
set_bits |= GDK_TOPLEVEL_STATE_MINIMIZED; set_bits |= GDK_TOPLEVEL_STATE_MINIMIZED;
else else
@ -2870,6 +2835,7 @@ gdk_event_translate (MSG *msg,
else else
unset_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED; unset_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED;
gdk_surface_set_is_mapped (window, !!IsWindowVisible (msg->hwnd));
gdk_synthesize_surface_state (window, unset_bits, set_bits); gdk_synthesize_surface_state (window, unset_bits, set_bits);
new_state = window->state; new_state = window->state;
@ -2890,7 +2856,7 @@ gdk_event_translate (MSG *msg,
{ {
if (!IsIconic (msg->hwnd) && if (!IsIconic (msg->hwnd) &&
!GDK_SURFACE_DESTROYED (window)) !GDK_SURFACE_DESTROYED (window))
_gdk_win32_emit_configure_event (window); gdk_surface_request_layout (window);
} }
if ((windowpos->flags & SWP_HIDEWINDOW) && if ((windowpos->flags & SWP_HIDEWINDOW) &&

View File

@ -274,11 +274,6 @@ _gdk_win32_surface_state_to_string (GdkToplevelState state)
if (state & GDK_TOPLEVEL_STATE_ ## x) \ if (state & GDK_TOPLEVEL_STATE_ ## x) \
(bufp += sprintf (bufp, "%s" #x, s), s = "|") (bufp += sprintf (bufp, "%s" #x, s), s = "|")
/* For clarity, also show the complement of WITHDRAWN, i.e. "MAPPED" */
if (!(state & GDK_TOPLEVEL_STATE_WITHDRAWN))
(bufp += sprintf (bufp, "MAPPED"), s = "|");
BIT (WITHDRAWN);
BIT (MINIMIZED); BIT (MINIMIZED);
BIT (MAXIMIZED); BIT (MAXIMIZED);
BIT (STICKY); BIT (STICKY);

View File

@ -407,7 +407,6 @@ GdkSurface *gdk_win32_display_get_root_window (GdkDisplay *display);
/* Distributed display manager implementation */ /* Distributed display manager implementation */
GdkDisplay *_gdk_win32_display_open (const char *display_name); GdkDisplay *_gdk_win32_display_open (const char *display_name);
void _gdk_win32_append_event (GdkEvent *event); void _gdk_win32_append_event (GdkEvent *event);
void _gdk_win32_emit_configure_event (GdkSurface *window);
guint32 _gdk_win32_keymap_get_decimal_mark (GdkWin32Keymap *keymap); guint32 _gdk_win32_keymap_get_decimal_mark (GdkWin32Keymap *keymap);

View File

@ -1006,9 +1006,7 @@ gdk_win32_surface_hide (GdkSurface *window)
_gdk_win32_surface_state_to_string (window->state))); _gdk_win32_surface_state_to_string (window->state)));
if (GDK_SURFACE_IS_MAPPED (window)) if (GDK_SURFACE_IS_MAPPED (window))
gdk_synthesize_surface_state (window, gdk_surface_set_is_mapped (window, FALSE);
0,
GDK_TOPLEVEL_STATE_WITHDRAWN);
_gdk_surface_clear_update_area (window); _gdk_surface_clear_update_area (window);
@ -1190,7 +1188,7 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
out: out:
surface->inhibit_configure = FALSE; surface->inhibit_configure = FALSE;
_gdk_win32_emit_configure_event (window); gdk_surface_request_layout (window);
} }
void void
@ -1217,6 +1215,7 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
int height, int height,
GdkPopupLayout *layout) GdkPopupLayout *layout)
{ {
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
GdkMonitor *monitor; GdkMonitor *monitor;
GdkRectangle bounds; GdkRectangle bounds;
GdkRectangle final_rect; GdkRectangle final_rect;
@ -1229,6 +1228,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface, gdk_surface_layout_popup_helper (surface,
width, width,
height, height,
impl->margins.left,
impl->margins.right,
impl->margins.top,
impl->margins.bottom,
monitor, monitor,
&bounds, &bounds,
layout, layout,
@ -1257,7 +1260,7 @@ static void
show_popup (GdkSurface *surface) show_popup (GdkSurface *surface)
{ {
gdk_win32_surface_raise (surface); gdk_win32_surface_raise (surface);
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (surface, TRUE);
show_window_internal (surface, FALSE, FALSE); show_window_internal (surface, FALSE, FALSE);
gdk_surface_invalidate_rect (surface, NULL); gdk_surface_invalidate_rect (surface, NULL);
} }
@ -4013,7 +4016,7 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
rect.bottom != new_rect.bottom)) rect.bottom != new_rect.bottom))
{ {
context->native_move_resize_pending = TRUE; context->native_move_resize_pending = TRUE;
_gdk_win32_do_emit_configure_event (window, new_rect); gdk_surface_request_layout (window);
} }
else if (context->op == GDK_WIN32_DRAGOP_MOVE && else if (context->op == GDK_WIN32_DRAGOP_MOVE &&
(rect.left != new_rect.left || (rect.left != new_rect.left ||
@ -4021,7 +4024,7 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
{ {
context->native_move_resize_pending = FALSE; context->native_move_resize_pending = FALSE;
_gdk_win32_do_emit_configure_event (window, new_rect); gdk_surface_request_layout (window);
if (impl->layered) if (impl->layered)
{ {
@ -4615,8 +4618,6 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
//impl_class->beep = gdk_x11_surface_beep; //impl_class->beep = gdk_x11_surface_beep;
impl_class->set_shadow_width = gdk_win32_surface_set_shadow_width;
impl_class->destroy_notify = gdk_win32_surface_destroy_notify; impl_class->destroy_notify = gdk_win32_surface_destroy_notify;
impl_class->drag_begin = _gdk_win32_surface_drag_begin; impl_class->drag_begin = _gdk_win32_surface_drag_begin;
impl_class->create_gl_context = _gdk_win32_surface_create_gl_context; impl_class->create_gl_context = _gdk_win32_surface_create_gl_context;
@ -4921,7 +4922,7 @@ show_surface (GdkSurface *surface)
was_mapped = GDK_SURFACE_IS_MAPPED (surface); was_mapped = GDK_SURFACE_IS_MAPPED (surface);
if (!was_mapped) if (!was_mapped)
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (surface, TRUE);
gdk_win32_surface_show (surface, FALSE); gdk_win32_surface_show (surface, FALSE);
@ -4992,6 +4993,15 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
show_surface (surface); show_surface (surface);
if (size.shadow.is_valid)
{
gdk_win32_surface_set_shadow_width (surface,
size.shadow.left,
size.shadow.right,
size.shadow.top,
size.shadow.bottom);
}
return TRUE; return TRUE;
} }

View File

@ -566,7 +566,7 @@ gdk_check_edge_constraints_changed (GdkSurface *surface)
* messing around with shifts, just make the passed value and GDK's * messing around with shifts, just make the passed value and GDK's
* enum values match by shifting to the first tiled state. * enum values match by shifting to the first tiled state.
*/ */
toplevel->edge_constraints = constraints[0] << 9; toplevel->edge_constraints = constraints[0] << 8;
XFree (constraints); XFree (constraints);
} }
@ -620,7 +620,6 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
{ {
Window xwindow; Window xwindow;
GdkSurface *surface; GdkSurface *surface;
gboolean is_substructure;
GdkX11Surface *surface_impl = NULL; GdkX11Surface *surface_impl = NULL;
GdkX11Screen *x11_screen = NULL; GdkX11Screen *x11_screen = NULL;
GdkToplevelX11 *toplevel = NULL; GdkToplevelX11 *toplevel = NULL;
@ -629,18 +628,9 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
event = NULL; event = NULL;
/* Find the GdkSurface that this event relates to. If that's
* not the same as the surface that the event was sent to,
* we are getting an event from SubstructureNotifyMask.
* We ignore such events for internal operation, but we
* need to report them to the application because of
* GDK_SUBSTRUCTURE_MASK (which should be removed at next
* opportunity.) The most likely reason for getting these
* events is when we are used in the Metacity or Mutter
* window managers.
*/
xwindow = get_event_xwindow (xevent); xwindow = get_event_xwindow (xevent);
is_substructure = xwindow != xevent->xany.window; if (xwindow != xevent->xany.window)
return NULL;
surface = gdk_x11_surface_lookup_for_display (display, xwindow); surface = gdk_x11_surface_lookup_for_display (display, xwindow);
if (surface) if (surface)
@ -664,7 +654,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
goto done; goto done;
} }
if (xevent->type == DestroyNotify && !is_substructure) if (xevent->type == DestroyNotify)
{ {
x11_screen = GDK_X11_DISPLAY (display)->screen; x11_screen = GDK_X11_DISPLAY (display)->screen;
@ -793,14 +783,11 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
g_message ("destroy notify:\twindow: %ld", g_message ("destroy notify:\twindow: %ld",
xevent->xdestroywindow.window)); xevent->xdestroywindow.window));
if (!is_substructure) if (surface)
{ event = gdk_delete_event_new (surface);
if (surface)
event = gdk_delete_event_new (surface);
if (surface && GDK_SURFACE_XID (surface) != x11_screen->xroot_window) if (surface && GDK_SURFACE_XID (surface) != x11_screen->xroot_window)
gdk_surface_destroy_notify (surface); gdk_surface_destroy_notify (surface);
}
break; break;
@ -809,7 +796,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
g_message ("unmap notify:\t\twindow: %ld", g_message ("unmap notify:\t\twindow: %ld",
xevent->xmap.window)); xevent->xmap.window));
if (surface && !is_substructure) if (surface)
{ {
/* If the WM supports the _NET_WM_STATE_HIDDEN hint, we do not want to /* If the WM supports the _NET_WM_STATE_HIDDEN hint, we do not want to
* interpret UnmapNotify events as implying iconic state. * interpret UnmapNotify events as implying iconic state.
@ -852,7 +839,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
g_message ("map notify:\t\twindow: %ld", g_message ("map notify:\t\twindow: %ld",
xevent->xmap.window)); xevent->xmap.window));
if (surface && !is_substructure) if (surface)
{ {
/* Unset minimized if it was set */ /* Unset minimized if it was set */
if (surface->state & GDK_TOPLEVEL_STATE_MINIMIZED) if (surface->state & GDK_TOPLEVEL_STATE_MINIMIZED)
@ -902,7 +889,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
} }
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
if (!is_substructure && toplevel && display_x11->use_sync && toplevel->pending_counter_value != 0) if (toplevel && display_x11->use_sync && toplevel->pending_counter_value != 0)
{ {
toplevel->configure_counter_value = toplevel->pending_counter_value; toplevel->configure_counter_value = toplevel->pending_counter_value;
toplevel->configure_counter_value_is_extended = toplevel->pending_counter_value_is_extended; toplevel->configure_counter_value_is_extended = toplevel->pending_counter_value_is_extended;
@ -914,10 +901,16 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
xevent->xconfigure.event == xevent->xconfigure.window) xevent->xconfigure.event == xevent->xconfigure.window)
{ {
int x, y; int x, y;
int c_w = (xevent->xconfigure.width + surface_impl->surface_scale - 1) / surface_impl->surface_scale; int configured_width;
int c_h = (xevent->xconfigure.height + surface_impl->surface_scale - 1) / surface_impl->surface_scale; int configured_height;
int new_abs_x, new_abs_y;
event = gdk_configure_event_new (surface, c_w, c_h); configured_width =
(xevent->xconfigure.width + surface_impl->surface_scale - 1) /
surface_impl->surface_scale;
configured_height =
(xevent->xconfigure.height + surface_impl->surface_scale - 1) /
surface_impl->surface_scale;
if (!xevent->xconfigure.send_event && if (!xevent->xconfigure.send_event &&
!xevent->xconfigure.override_redirect && !xevent->xconfigure.override_redirect &&
@ -946,47 +939,45 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
x = xevent->xconfigure.x / surface_impl->surface_scale; x = xevent->xconfigure.x / surface_impl->surface_scale;
y = xevent->xconfigure.y / surface_impl->surface_scale; y = xevent->xconfigure.y / surface_impl->surface_scale;
} }
if (!is_substructure)
{
int new_abs_x, new_abs_y;
new_abs_x = x; new_abs_x = x;
new_abs_y = y; new_abs_y = y;
surface_impl->abs_x = new_abs_x; surface_impl->abs_x = new_abs_x;
surface_impl->abs_y = new_abs_y; surface_impl->abs_y = new_abs_y;
if (surface->parent) if (surface->parent)
{ {
GdkX11Surface *parent_impl = GdkX11Surface *parent_impl =
GDK_X11_SURFACE (surface->parent); GDK_X11_SURFACE (surface->parent);
surface->x = new_abs_x - parent_impl->abs_x; surface->x = new_abs_x - parent_impl->abs_x;
surface->y = new_abs_y - parent_impl->abs_y; surface->y = new_abs_y - parent_impl->abs_y;
} }
if (surface_impl->unscaled_width != xevent->xconfigure.width || if (surface_impl->unscaled_width != xevent->xconfigure.width ||
surface_impl->unscaled_height != xevent->xconfigure.height) surface_impl->unscaled_height != xevent->xconfigure.height)
{ {
surface_impl->unscaled_width = xevent->xconfigure.width; surface_impl->unscaled_width = xevent->xconfigure.width;
surface_impl->unscaled_height = xevent->xconfigure.height; surface_impl->unscaled_height = xevent->xconfigure.height;
gdk_configure_event_get_size (event, &surface->width, &surface->height);
_gdk_surface_update_size (surface); surface_impl->next_layout.configured_width = configured_width;
_gdk_x11_surface_update_size (surface_impl); surface_impl->next_layout.configured_height = configured_height;
} surface_impl->next_layout.surface_geometry_dirty = TRUE;
surface_impl->next_layout.configure_pending = TRUE;
gdk_surface_request_layout (surface);
}
if (surface->resize_count >= 1) if (surface->resize_count >= 1)
{ {
surface->resize_count -= 1; surface->resize_count -= 1;
if (surface->resize_count == 0) if (surface->resize_count == 0)
_gdk_x11_moveresize_configure_done (display, surface); _gdk_x11_moveresize_configure_done (display, surface);
} }
gdk_x11_surface_update_popups (surface); gdk_x11_surface_update_popups (surface);
gdk_x11_surface_enter_leave_monitors (surface); gdk_x11_surface_enter_leave_monitors (surface);
}
} }
break; break;

View File

@ -2036,7 +2036,7 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
if (gdk_x11_surface_get_group (surface)) if (gdk_x11_surface_get_group (surface))
gdk_x11_surface_set_group (x11_drag->ipc_surface, surface); gdk_x11_surface_set_group (x11_drag->ipc_surface, surface);
gdk_synthesize_surface_state (x11_drag->ipc_surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (x11_drag->ipc_surface, TRUE);
gdk_x11_surface_show (x11_drag->ipc_surface, FALSE); gdk_x11_surface_show (x11_drag->ipc_surface, FALSE);
x11_drag->drag_surface = create_drag_surface (display); x11_drag->drag_surface = create_drag_surface (display);

View File

@ -463,7 +463,7 @@ on_surface_state_changed (GdkGLContext *context)
{ {
GdkSurface *surface = gdk_gl_context_get_surface (context); GdkSurface *surface = gdk_gl_context_get_surface (context);
if ((surface->state & GDK_TOPLEVEL_STATE_WITHDRAWN) == 0) if (GDK_SURFACE_IS_MAPPED (surface))
return; return;
/* If we're about to withdraw the surface, then we don't care if the frame is /* If we're about to withdraw the surface, then we don't care if the frame is

View File

@ -98,6 +98,14 @@ const int _gdk_x11_event_mask_table[21] =
ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */ ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
}; };
typedef struct {
GdkX11Surface parent_instance;
} GdkX11Toplevel;
typedef struct {
GdkX11SurfaceClass parent_class;
} GdkX11ToplevelClass;
const int _gdk_x11_event_mask_table_size = G_N_ELEMENTS (_gdk_x11_event_mask_table); const int _gdk_x11_event_mask_table_size = G_N_ELEMENTS (_gdk_x11_event_mask_table);
/* Forward declarations */ /* Forward declarations */
@ -111,6 +119,14 @@ static void gdk_x11_toplevel_state_callback (GdkSurface *surface);
static gboolean gdk_x11_toplevel_event_callback (GdkSurface *surface, static gboolean gdk_x11_toplevel_event_callback (GdkSurface *surface,
GdkEvent *gdk_event); GdkEvent *gdk_event);
static void gdk_x11_surface_toplevel_resize (GdkSurface *surface,
int width,
int height);
static void gdk_x11_surface_set_geometry_hints (GdkSurface *surface,
const GdkGeometry *geometry,
GdkSurfaceHints geom_mask);
/* Return whether time1 is considered later than time2 as far as xserver /* Return whether time1 is considered later than time2 as far as xserver
* time is concerned. Accounts for wraparound. * time is concerned. Accounts for wraparound.
*/ */
@ -192,6 +208,206 @@ gdk_x11_surface_get_unscaled_size (GdkSurface *surface,
*unscaled_height = impl->unscaled_height; *unscaled_height = impl->unscaled_height;
} }
static void
update_shadow_size (GdkSurface *surface,
int shadow_left,
int shadow_right,
int shadow_top,
int shadow_bottom)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
Atom frame_extents;
gulong data[4];
if (impl->shadow_left == shadow_left &&
impl->shadow_right == shadow_right &&
impl->shadow_top == shadow_top &&
impl->shadow_bottom == shadow_bottom)
return;
impl->shadow_left = shadow_left;
impl->shadow_right = shadow_right;
impl->shadow_top = shadow_top;
impl->shadow_bottom = shadow_bottom;
data[0] = shadow_left * impl->surface_scale;
data[1] = shadow_right * impl->surface_scale;
data[2] = shadow_top * impl->surface_scale;
data[3] = shadow_bottom * impl->surface_scale;
frame_extents = gdk_x11_get_xatom_by_name_for_display (gdk_surface_get_display (surface),
"_GTK_FRAME_EXTENTS");
XChangeProperty (GDK_SURFACE_XDISPLAY (surface),
GDK_SURFACE_XID (surface),
frame_extents, XA_CARDINAL,
32, PropModeReplace,
(guchar *) &data, 4);
}
#define UPDATE_GEOMETRY TRUE
#define DONT_UPDATE_GEOMETRY FALSE
static gboolean
compute_toplevel_size (GdkSurface *surface,
gboolean update_geometry,
int *width,
int *height)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
int bounds_width, bounds_height;
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 (GDK_TOPLEVEL (surface), &size);
if (size.shadow.is_valid && update_geometry)
{
update_shadow_size (surface,
size.shadow.left,
size.shadow.right,
size.shadow.top,
size.shadow.bottom);
}
if (update_geometry)
{
GdkGeometry geometry;
GdkSurfaceHints mask;
if (gdk_toplevel_layout_get_resizable (impl->toplevel_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 = size.width;
geometry.max_height = geometry.min_height = size.height;
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
}
gdk_x11_surface_set_geometry_hints (surface, &geometry, mask);
}
if (!(surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_TILED |
GDK_TOPLEVEL_STATE_TOP_TILED |
GDK_TOPLEVEL_STATE_RIGHT_TILED |
GDK_TOPLEVEL_STATE_BOTTOM_TILED |
GDK_TOPLEVEL_STATE_LEFT_TILED |
GDK_TOPLEVEL_STATE_MINIMIZED)) &&
(!impl->next_layout.configure_pending || surface->resize_count > 0))
{
GdkToplevelX11 *toplevel = _gdk_x11_surface_get_toplevel (surface);
GdkGeometry geometry;
GdkSurfaceHints mask;
geometry = toplevel->last_geometry_hints;
mask = toplevel->last_geometry_hints_mask;
gdk_surface_constrain_size (&geometry, mask,
size.width, size.height,
&size.width, &size.height);
if ((impl->last_computed_width != size.width ||
impl->last_computed_height != size.height) &&
(impl->next_layout.configured_width != size.width ||
impl->next_layout.configured_height != size.height))
{
*width = size.width;
*height = size.height;
impl->last_computed_width = size.width;
impl->last_computed_height = size.height;
return TRUE;
}
}
return FALSE;
}
static gboolean
compute_size_idle (gpointer user_data)
{
GdkSurface *surface = user_data;
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
int width, height;
impl->compute_size_source_id = 0;
if (compute_toplevel_size (surface, UPDATE_GEOMETRY, &width, &height))
gdk_x11_surface_toplevel_resize (surface, width, height);
return G_SOURCE_REMOVE;
}
static void
gdk_x11_surface_request_layout (GdkSurface *surface)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
if (!impl->compute_size_source_id &&
GDK_IS_TOPLEVEL (surface))
{
impl->compute_size_source_id = g_idle_add_full (G_PRIORITY_HIGH - 10,
compute_size_idle,
surface,
NULL);
}
}
static gboolean
gdk_x11_surface_compute_size (GdkSurface *surface)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
if (GDK_IS_TOPLEVEL (surface))
{
int width, height;
if (compute_toplevel_size (surface, UPDATE_GEOMETRY, &width, &height))
gdk_x11_surface_toplevel_resize (surface, width, height);
if (surface->resize_count == 0)
{
surface->width = impl->next_layout.configured_width;
surface->height = impl->next_layout.configured_height;
_gdk_surface_update_size (surface);
_gdk_x11_surface_update_size (impl);
}
impl->next_layout.surface_geometry_dirty = FALSE;
impl->next_layout.configure_pending = FALSE;
}
else
{
surface->width = impl->next_layout.configured_width;
surface->height = impl->next_layout.configured_height;
_gdk_surface_update_size (surface);
_gdk_x11_surface_update_size (impl);
impl->next_layout.surface_geometry_dirty = FALSE;
}
return surface->resize_count > 0;
}
gboolean gboolean
gdk_x11_surface_supports_edge_constraints (GdkSurface *surface) gdk_x11_surface_supports_edge_constraints (GdkSurface *surface)
{ {
@ -837,6 +1053,19 @@ on_frame_clock_before_paint (GdkFrameClock *clock,
gdk_x11_surface_begin_frame (surface, FALSE); gdk_x11_surface_begin_frame (surface, FALSE);
} }
static void
on_frame_clock_after_update (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
if (impl->compute_size_source_id)
{
g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
compute_size_idle (surface);
}
}
static void static void
on_frame_clock_after_paint (GdkFrameClock *clock, on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface) GdkSurface *surface)
@ -859,6 +1088,8 @@ connect_frame_clock (GdkSurface *surface)
g_signal_connect (frame_clock, "before-paint", g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface); G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect_after (frame_clock, "update",
G_CALLBACK (on_frame_clock_after_update), surface);
g_signal_connect (frame_clock, "after-paint", g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface); G_CALLBACK (on_frame_clock_after_paint), surface);
@ -878,6 +1109,8 @@ disconnect_frame_clock (GdkSurface *surface)
g_signal_handlers_disconnect_by_func (frame_clock, g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface); on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_update, surface);
g_signal_handlers_disconnect_by_func (frame_clock, g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface); on_frame_clock_after_paint, surface);
@ -1168,7 +1401,7 @@ update_wm_hints (GdkSurface *surface,
if (!force && if (!force &&
!toplevel->is_leader && !toplevel->is_leader &&
surface->state & GDK_TOPLEVEL_STATE_WITHDRAWN) !GDK_SURFACE_IS_MAPPED (surface))
return; return;
wm_hints.flags = StateHint | InputHint; wm_hints.flags = StateHint | InputHint;
@ -1375,9 +1608,7 @@ gdk_x11_surface_withdraw (GdkSurface *surface)
if (!surface->destroyed) if (!surface->destroyed)
{ {
if (GDK_SURFACE_IS_MAPPED (surface)) if (GDK_SURFACE_IS_MAPPED (surface))
gdk_synthesize_surface_state (surface, gdk_surface_set_is_mapped (surface, FALSE);
0,
GDK_TOPLEVEL_STATE_WITHDRAWN);
g_assert (!GDK_SURFACE_IS_MAPPED (surface)); g_assert (!GDK_SURFACE_IS_MAPPED (surface));
XWithdrawWindow (GDK_SURFACE_XDISPLAY (surface), XWithdrawWindow (GDK_SURFACE_XDISPLAY (surface),
@ -1388,6 +1619,8 @@ gdk_x11_surface_withdraw (GdkSurface *surface)
static void static void
gdk_x11_surface_hide (GdkSurface *surface) gdk_x11_surface_hide (GdkSurface *surface)
{ {
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
/* We'll get the unmap notify eventually, and handle it then, /* We'll get the unmap notify eventually, and handle it then,
* but checking here makes things more consistent if we are * but checking here makes things more consistent if we are
* just doing stuff ourself. * just doing stuff ourself.
@ -1395,6 +1628,9 @@ gdk_x11_surface_hide (GdkSurface *surface)
_gdk_x11_surface_grab_check_unmap (surface, _gdk_x11_surface_grab_check_unmap (surface,
NextRequest (GDK_SURFACE_XDISPLAY (surface))); NextRequest (GDK_SURFACE_XDISPLAY (surface)));
g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
gdk_x11_surface_withdraw (surface); gdk_x11_surface_withdraw (surface);
} }
@ -1424,6 +1660,9 @@ x11_surface_move (GdkSurface *surface,
surface->x = x; surface->x = x;
surface->y = y; surface->y = y;
} }
impl->next_layout.surface_geometry_dirty = TRUE;
gdk_surface_request_layout (surface);
} }
} }
@ -1450,15 +1689,20 @@ x11_surface_resize (GdkSurface *surface,
{ {
impl->unscaled_width = width * impl->surface_scale; impl->unscaled_width = width * impl->surface_scale;
impl->unscaled_height = height * impl->surface_scale; impl->unscaled_height = height * impl->surface_scale;
surface->width = width; impl->next_layout.configured_width = width;
surface->height = height; impl->next_layout.configured_height = height;
_gdk_surface_update_size (surface); impl->next_layout.surface_geometry_dirty = TRUE;
_gdk_x11_surface_update_size (GDK_X11_SURFACE (surface)); gdk_surface_request_layout (surface);
} }
else else
{ {
if (width * impl->surface_scale != impl->unscaled_width || height * impl->surface_scale != impl->unscaled_height) if (width * impl->surface_scale != impl->unscaled_width ||
surface->resize_count += 1; height * impl->surface_scale != impl->unscaled_height)
{
surface->resize_count++;
if (surface->resize_count == 1)
gdk_surface_freeze_updates (surface);
}
} }
} }
@ -1491,10 +1735,10 @@ x11_surface_move_resize (GdkSurface *surface,
impl->unscaled_width = width * impl->surface_scale; impl->unscaled_width = width * impl->surface_scale;
impl->unscaled_height = height * impl->surface_scale; impl->unscaled_height = height * impl->surface_scale;
surface->width = width; impl->next_layout.configured_width = width;
surface->height = height; impl->next_layout.configured_height = height;
impl->next_layout.surface_geometry_dirty = TRUE;
_gdk_x11_surface_update_size (GDK_X11_SURFACE (surface)); gdk_surface_request_layout (surface);
if (surface->parent) if (surface->parent)
{ {
@ -1509,8 +1753,13 @@ x11_surface_move_resize (GdkSurface *surface,
} }
else else
{ {
if (width * impl->surface_scale != impl->unscaled_width || height * impl->surface_scale != impl->unscaled_height) if (width * impl->surface_scale != impl->unscaled_width ||
surface->resize_count += 1; height * impl->surface_scale != impl->unscaled_height)
{
surface->resize_count++;
if (surface->resize_count == 1)
gdk_surface_freeze_updates (surface);
}
} }
} }
@ -1555,6 +1804,7 @@ gdk_x11_surface_layout_popup (GdkSurface *surface,
int height, int height,
GdkPopupLayout *layout) GdkPopupLayout *layout)
{ {
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkMonitor *monitor; GdkMonitor *monitor;
GdkRectangle bounds; GdkRectangle bounds;
GdkRectangle final_rect; GdkRectangle final_rect;
@ -1567,6 +1817,10 @@ gdk_x11_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface, gdk_surface_layout_popup_helper (surface,
width, width,
height, height,
impl->shadow_left,
impl->shadow_right,
impl->shadow_top,
impl->shadow_bottom,
monitor, monitor,
&bounds, &bounds,
layout, layout,
@ -1596,7 +1850,7 @@ static void
show_popup (GdkSurface *surface) show_popup (GdkSurface *surface)
{ {
gdk_x11_surface_raise (surface); gdk_x11_surface_raise (surface);
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (surface, TRUE);
gdk_x11_surface_show (surface, FALSE); gdk_x11_surface_show (surface, FALSE);
gdk_surface_invalidate_rect (surface, NULL); gdk_surface_invalidate_rect (surface, NULL);
} }
@ -1721,10 +1975,6 @@ gdk_x11_surface_enter_leave_monitors (GdkSurface *surface)
} }
} }
static void gdk_x11_surface_set_geometry_hints (GdkSurface *surface,
const GdkGeometry *geometry,
GdkSurfaceHints geom_mask);
void void
_gdk_x11_surface_set_surface_scale (GdkSurface *surface, _gdk_x11_surface_set_surface_scale (GdkSurface *surface,
int scale) int scale)
@ -2815,31 +3065,6 @@ gdk_x11_surface_set_utf8_property (GdkSurface *surface,
} }
} }
static void
gdk_x11_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
Atom frame_extents;
gulong data[4] = {
left * impl->surface_scale,
right * impl->surface_scale,
top * impl->surface_scale,
bottom * impl->surface_scale
};
frame_extents = gdk_x11_get_xatom_by_name_for_display (gdk_surface_get_display (surface),
"_GTK_FRAME_EXTENTS");
XChangeProperty (GDK_SURFACE_XDISPLAY (surface),
GDK_SURFACE_XID (surface),
frame_extents, XA_CARDINAL,
32, PropModeReplace,
(guchar *) &data, 4);
}
/** /**
* gdk_x11_surface_set_theme_variant: * gdk_x11_surface_set_theme_variant:
* @surface: (type GdkX11Surface): a #GdkSurface * @surface: (type GdkX11Surface): a #GdkSurface
@ -4095,6 +4320,9 @@ _gdk_x11_moveresize_configure_done (GdkDisplay *display,
XEvent *tmp_event; XEvent *tmp_event;
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE); MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
gdk_surface_thaw_updates (surface);
gdk_surface_request_layout (surface);
if (!mv_resize || surface != mv_resize->moveresize_surface) if (!mv_resize || surface != mv_resize->moveresize_surface)
return FALSE; return FALSE;
@ -4565,9 +4793,10 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
impl_class->drag_begin = _gdk_x11_surface_drag_begin; impl_class->drag_begin = _gdk_x11_surface_drag_begin;
impl_class->get_scale_factor = gdk_x11_surface_get_scale_factor; impl_class->get_scale_factor = gdk_x11_surface_get_scale_factor;
impl_class->set_opaque_region = gdk_x11_surface_set_opaque_region; impl_class->set_opaque_region = gdk_x11_surface_set_opaque_region;
impl_class->set_shadow_width = gdk_x11_surface_set_shadow_width;
impl_class->create_gl_context = gdk_x11_surface_create_gl_context; impl_class->create_gl_context = gdk_x11_surface_create_gl_context;
impl_class->get_unscaled_size = gdk_x11_surface_get_unscaled_size; impl_class->get_unscaled_size = gdk_x11_surface_get_unscaled_size;
impl_class->request_layout = gdk_x11_surface_request_layout;
impl_class->compute_size = gdk_x11_surface_compute_size;
} }
#define LAST_PROP 1 #define LAST_PROP 1
@ -4696,14 +4925,6 @@ gdk_x11_popup_iface_init (GdkPopupInterface *iface)
iface->get_position_y = gdk_x11_popup_get_position_y; iface->get_position_y = gdk_x11_popup_get_position_y;
} }
typedef struct {
GdkX11Surface parent_instance;
} GdkX11Toplevel;
typedef struct {
GdkX11SurfaceClass parent_class;
} GdkX11ToplevelClass;
static void gdk_x11_toplevel_iface_init (GdkToplevelInterface *iface); static void gdk_x11_toplevel_iface_init (GdkToplevelInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GdkX11Toplevel, gdk_x11_toplevel, GDK_TYPE_X11_SURFACE, G_DEFINE_TYPE_WITH_CODE (GdkX11Toplevel, gdk_x11_toplevel, GDK_TYPE_X11_SURFACE,
@ -4849,59 +5070,27 @@ gdk_x11_toplevel_class_init (GdkX11ToplevelClass *class)
gdk_toplevel_install_properties (object_class, LAST_PROP); gdk_toplevel_install_properties (object_class, LAST_PROP);
} }
static gboolean static void
gdk_x11_toplevel_present (GdkToplevel *toplevel, gdk_x11_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout) GdkToplevelLayout *layout)
{ {
GdkSurface *surface = GDK_SURFACE (toplevel); GdkSurface *surface = GDK_SURFACE (toplevel);
GdkDisplay *display = gdk_surface_get_display (surface); GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
int bounds_width, bounds_height;
int width, height; int width, height;
GdkGeometry geometry;
GdkSurfaceHints mask;
gboolean was_mapped; gboolean was_mapped;
if (surface->destroyed)
return;
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
gdk_x11_surface_unminimize (surface); gdk_x11_surface_unminimize (surface);
monitor = gdk_display_get_monitor_at_surface (display, surface); g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
if (monitor) impl->toplevel_layout = gdk_toplevel_layout_copy (layout);
{
GdkRectangle workarea;
gdk_x11_monitor_get_workarea (monitor, &workarea); if (compute_toplevel_size (surface, DONT_UPDATE_GEOMETRY, &width, &height))
bounds_width = workarea.width; gdk_x11_surface_toplevel_resize (surface, width, height);
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 = 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_x11_surface_set_geometry_hints (surface, &geometry, mask);
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
gdk_x11_surface_toplevel_resize (surface, width, height);
if (gdk_toplevel_layout_get_maximized (layout)) if (gdk_toplevel_layout_get_maximized (layout))
gdk_x11_surface_maximize (surface); gdk_x11_surface_maximize (surface);
@ -4921,20 +5110,16 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
else else
gdk_x11_surface_unfullscreen (surface); gdk_x11_surface_unfullscreen (surface);
if (surface->destroyed) impl->next_layout.surface_geometry_dirty = TRUE;
return TRUE; gdk_surface_request_layout (surface);
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
if (!was_mapped) if (!was_mapped)
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (surface, TRUE);
gdk_x11_surface_show (surface, was_mapped); gdk_x11_surface_show (surface, was_mapped);
if (!was_mapped) if (!was_mapped)
gdk_surface_invalidate_rect (surface, NULL); gdk_surface_invalidate_rect (surface, NULL);
return TRUE;
} }
static gboolean static gboolean
@ -5100,7 +5285,7 @@ gdk_x11_drag_surface_present (GdkDragSurface *drag_surface,
GdkSurface *surface = GDK_SURFACE (drag_surface); GdkSurface *surface = GDK_SURFACE (drag_surface);
gdk_x11_surface_toplevel_resize (surface, width, height); gdk_x11_surface_toplevel_resize (surface, width, height);
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); gdk_surface_set_is_mapped (surface, TRUE);
gdk_x11_surface_show (surface, FALSE); gdk_x11_surface_show (surface, FALSE);
gdk_surface_invalidate_rect (surface, NULL); gdk_surface_invalidate_rect (surface, NULL);

View File

@ -59,6 +59,11 @@ struct _GdkX11Surface
int surface_scale; int surface_scale;
int shadow_left;
int shadow_right;
int shadow_top;
int shadow_bottom;
/* Width and height not divided by surface_scale - this matters in the /* Width and height not divided by surface_scale - this matters in the
* corner-case where the window manager assigns us a size that isn't * corner-case where the window manager assigns us a size that isn't
* a multiple of surface_scale - for example for a maximized window * a multiple of surface_scale - for example for a maximized window
@ -67,6 +72,20 @@ struct _GdkX11Surface
int unscaled_width; int unscaled_width;
int unscaled_height; int unscaled_height;
int last_computed_width;
int last_computed_height;
GdkToplevelLayout *toplevel_layout;
struct {
int configured_width;
int configured_height;
gboolean configure_pending;
gboolean surface_geometry_dirty;
} next_layout;
guint compute_size_source_id;
cairo_surface_t *cairo_surface; cairo_surface_t *cairo_surface;
int abs_x; int abs_x;

View File

@ -322,7 +322,7 @@ swatch_size_allocate (GtkWidget *widget,
}, -1); }, -1);
if (swatch->popover) if (swatch->popover)
gtk_native_check_resize (GTK_NATIVE (swatch->popover)); gtk_popover_present (GTK_POPOVER (swatch->popover));
} }
static void static void

View File

@ -144,7 +144,7 @@ gtk_column_view_title_size_allocate (GtkWidget *widget,
} }
if (self->popup_menu) if (self->popup_menu)
gtk_native_check_resize (GTK_NATIVE (self->popup_menu)); gtk_popover_present (GTK_POPOVER (self->popup_menu));
} }
static void static void

View File

@ -376,7 +376,7 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
gtk_widget_set_size_request (priv->popup_widget, gtk_widget_set_size_request (priv->popup_widget,
MAX (width, menu_width), -1); MAX (width, menu_width), -1);
gtk_native_check_resize (GTK_NATIVE (priv->popup_widget)); gtk_popover_present (GTK_POPOVER (priv->popup_widget));
} }
static void static void

View File

@ -147,22 +147,22 @@ gtk_drag_icon_move_resize (GtkDragIcon *icon)
} }
static void static void
gtk_drag_icon_native_check_resize (GtkNative *native) gtk_drag_icon_present (GtkDragIcon *icon)
{ {
GtkDragIcon *icon = GTK_DRAG_ICON (native); GtkWidget *widget = GTK_WIDGET (icon);
GtkWidget *widget = GTK_WIDGET (native);
if (!_gtk_widget_get_alloc_needed (widget)) if (!_gtk_widget_get_alloc_needed (widget))
gtk_widget_ensure_allocate (widget); gtk_widget_ensure_allocate (widget);
else if (gtk_widget_get_visible (widget)) else if (gtk_widget_get_visible (widget))
{ gtk_drag_icon_move_resize (icon);
gtk_drag_icon_move_resize (icon); }
if (icon->surface)
gtk_widget_allocate (widget, static void
gdk_surface_get_width (icon->surface), gtk_drag_icon_native_layout (GtkNative *native,
gdk_surface_get_height (icon->surface), int width,
-1, NULL); int height)
} {
gtk_widget_allocate (GTK_WIDGET (native), width, height, -1, NULL);
} }
static void static void
@ -171,7 +171,7 @@ gtk_drag_icon_native_init (GtkNativeInterface *iface)
iface->get_surface = gtk_drag_icon_native_get_surface; iface->get_surface = gtk_drag_icon_native_get_surface;
iface->get_renderer = gtk_drag_icon_native_get_renderer; iface->get_renderer = gtk_drag_icon_native_get_renderer;
iface->get_surface_transform = gtk_drag_icon_native_get_surface_transform; iface->get_surface_transform = gtk_drag_icon_native_get_surface_transform;
iface->check_resize = gtk_drag_icon_native_check_resize; iface->layout = gtk_drag_icon_native_layout;
} }
static gboolean static gboolean
@ -197,6 +197,8 @@ gtk_drag_icon_realize (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_drag_icon_parent_class)->realize (widget); GTK_WIDGET_CLASS (gtk_drag_icon_parent_class)->realize (widget);
icon->renderer = gsk_renderer_new_for_surface (icon->surface); icon->renderer = gsk_renderer_new_for_surface (icon->surface);
gtk_native_realize (GTK_NATIVE (icon));
} }
static void static void
@ -204,6 +206,8 @@ gtk_drag_icon_unrealize (GtkWidget *widget)
{ {
GtkDragIcon *icon = GTK_DRAG_ICON (widget); GtkDragIcon *icon = GTK_DRAG_ICON (widget);
gtk_native_unrealize (GTK_NATIVE (icon));
GTK_WIDGET_CLASS (gtk_drag_icon_parent_class)->unrealize (widget); GTK_WIDGET_CLASS (gtk_drag_icon_parent_class)->unrealize (widget);
gsk_renderer_unrealize (icon->renderer); gsk_renderer_unrealize (icon->renderer);
@ -279,7 +283,7 @@ gtk_drag_icon_show (GtkWidget *widget)
_gtk_widget_set_visible_flag (widget, TRUE); _gtk_widget_set_visible_flag (widget, TRUE);
gtk_css_node_validate (gtk_widget_get_css_node (widget)); gtk_css_node_validate (gtk_widget_get_css_node (widget));
gtk_widget_realize (widget); gtk_widget_realize (widget);
gtk_drag_icon_native_check_resize (GTK_NATIVE (widget)); gtk_drag_icon_present (GTK_DRAG_ICON (widget));
gtk_widget_map (widget); gtk_widget_map (widget);
} }
@ -414,7 +418,8 @@ gtk_drag_icon_get_for_drag (GdkDrag *drag)
g_object_set_qdata_full (G_OBJECT (drag), drag_icon_quark, g_object_ref_sink (self), g_object_unref); g_object_set_qdata_full (G_OBJECT (drag), drag_icon_quark, g_object_ref_sink (self), g_object_unref);
gtk_widget_show (self); if (GTK_DRAG_ICON (self)->child != NULL)
gtk_widget_show (self);
} }
return self; return self;
@ -472,7 +477,10 @@ gtk_drag_icon_set_child (GtkDragIcon *self,
self->child = child; self->child = child;
if (self->child) if (self->child)
gtk_widget_set_parent (self->child, GTK_WIDGET (self)); {
gtk_widget_set_parent (self->child, GTK_WIDGET (self));
gtk_widget_show (GTK_WIDGET (self));
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CHILD]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CHILD]);
} }

View File

@ -383,7 +383,7 @@ gtk_drop_down_size_allocate (GtkWidget *widget,
gtk_widget_set_size_request (self->popup, width, -1); gtk_widget_set_size_request (self->popup, width, -1);
gtk_widget_queue_resize (self->popup); gtk_widget_queue_resize (self->popup);
gtk_native_check_resize (GTK_NATIVE (self->popup)); gtk_popover_present (GTK_POPOVER (self->popup));
} }
static gboolean static gboolean

View File

@ -113,7 +113,7 @@ gtk_emoji_chooser_child_size_allocate (GtkWidget *widget,
GTK_WIDGET_CLASS (gtk_emoji_chooser_child_parent_class)->size_allocate (widget, width, height, baseline); GTK_WIDGET_CLASS (gtk_emoji_chooser_child_parent_class)->size_allocate (widget, width, height, baseline);
if (child->variations) if (child->variations)
gtk_native_check_resize (GTK_NATIVE (child->variations)); gtk_popover_present (GTK_POPOVER (child->variations));
} }
static gboolean static gboolean

View File

@ -181,7 +181,6 @@ struct _GtkEntryPrivate
GtkWidget *text; GtkWidget *text;
GtkWidget *progress_widget; GtkWidget *progress_widget;
GtkWidget *emoji_chooser;
guint show_emoji_icon : 1; guint show_emoji_icon : 1;
guint editing_canceled : 1; /* Only used by GtkCellRendererText */ guint editing_canceled : 1; /* Only used by GtkCellRendererText */
@ -1452,8 +1451,6 @@ gtk_entry_dispose (GObject *object)
} }
g_clear_pointer (&priv->text, gtk_widget_unparent); g_clear_pointer (&priv->text, gtk_widget_unparent);
g_clear_pointer (&priv->emoji_chooser, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_entry_parent_class)->dispose (object); G_OBJECT_CLASS (gtk_entry_parent_class)->dispose (object);
} }
@ -1803,9 +1800,6 @@ gtk_entry_size_allocate (GtkWidget *widget,
if (completion) if (completion)
_gtk_entry_completion_resize_popup (completion); _gtk_entry_completion_resize_popup (completion);
} }
if (priv->emoji_chooser)
gtk_native_check_resize (GTK_NATIVE (priv->emoji_chooser));
} }
static void static void

View File

@ -1150,7 +1150,8 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
NULL, FALSE, 0.0, 0.0); NULL, FALSE, 0.0, 0.0);
gtk_tree_path_free (path); gtk_tree_path_free (path);
} }
gtk_native_check_resize (GTK_NATIVE (completion->popup_window));
gtk_popover_present (GTK_POPOVER (completion->popup_window));
} }
static void static void

View File

@ -727,23 +727,7 @@ gtk_expander_resize_toplevel (GtkExpander *expander)
if (GTK_IS_WINDOW (toplevel) && if (GTK_IS_WINDOW (toplevel) &&
gtk_widget_get_realized (toplevel)) gtk_widget_get_realized (toplevel))
{ gtk_widget_queue_resize (GTK_WIDGET (expander));
int toplevel_width, toplevel_height;
int child_height;
gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL, -1,
&child_height, NULL, NULL, NULL);
gtk_window_get_size (GTK_WINDOW (toplevel), &toplevel_width, &toplevel_height);
if (expander->expanded)
toplevel_height += child_height;
else
toplevel_height -= child_height;
gtk_window_resize (GTK_WINDOW (toplevel),
toplevel_width,
toplevel_height);
}
} }
} }

View File

@ -628,7 +628,7 @@ save_dialog_geometry (GtkFileChooserDialog *dialog)
window = GTK_WINDOW (dialog); window = GTK_WINDOW (dialog);
gtk_window_get_size (window, &width, &height); gtk_window_get_default_size (window, &width, &height);
g_settings_get (settings, SETTINGS_KEY_WINDOW_SIZE, "(ii)", &old_width, &old_height); g_settings_get (settings, SETTINGS_KEY_WINDOW_SIZE, "(ii)", &old_width, &old_height);
if (old_width != width || old_height != height) if (old_width != width || old_height != height)

View File

@ -7225,10 +7225,11 @@ gtk_file_chooser_widget_size_allocate (GtkWidget *widget,
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (widget); GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->size_allocate (widget, width, height, baseline); GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->size_allocate (widget, width, height, baseline);
if (impl->browse_files_popover) if (impl->browse_files_popover)
gtk_native_check_resize (GTK_NATIVE (impl->browse_files_popover)); gtk_popover_present (GTK_POPOVER (impl->browse_files_popover));
if (impl->rename_file_popover) if (impl->rename_file_popover)
gtk_native_check_resize (GTK_NATIVE (impl->rename_file_popover)); gtk_popover_present (GTK_POPOVER (impl->rename_file_popover));
} }
static void static void

View File

@ -130,8 +130,6 @@ struct _GtkHeaderBar
guint show_title_buttons : 1; guint show_title_buttons : 1;
guint track_default_decoration : 1; guint track_default_decoration : 1;
GdkToplevelState state;
}; };
typedef struct _GtkHeaderBarClass GtkHeaderBarClass; typedef struct _GtkHeaderBarClass GtkHeaderBarClass;
@ -613,7 +611,6 @@ gtk_header_bar_init (GtkHeaderBar *bar)
bar->title_widget = NULL; bar->title_widget = NULL;
bar->decoration_layout = NULL; bar->decoration_layout = NULL;
bar->show_title_buttons = TRUE; bar->show_title_buttons = TRUE;
bar->state = GDK_TOPLEVEL_STATE_WITHDRAWN;
bar->handle = gtk_window_handle_new (); bar->handle = gtk_window_handle_new ();
gtk_widget_set_parent (bar->handle, GTK_WIDGET (bar)); gtk_widget_set_parent (bar->handle, GTK_WIDGET (bar));

View File

@ -3276,7 +3276,7 @@ gtk_label_size_allocate (GtkWidget *widget,
} }
if (self->popup_menu) if (self->popup_menu)
gtk_native_check_resize (GTK_NATIVE (self->popup_menu)); gtk_popover_present (GTK_POPOVER (self->popup_menu));
} }
static void static void

View File

@ -77,6 +77,9 @@
#include "gtklayoutchild.h" #include "gtklayoutchild.h"
#include "gtkwidgetprivate.h" #include "gtkwidgetprivate.h"
#include "gtknative.h" #include "gtknative.h"
#include "gtkpopover.h"
#include "gtktexthandleprivate.h"
#include "gtktooltipwindowprivate.h"
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
#define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method) G_STMT_START { \ #define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method) G_STMT_START { \
@ -363,8 +366,15 @@ allocate_native_children (GtkWidget *widget)
child != NULL; child != NULL;
child = _gtk_widget_get_next_sibling (child)) child = _gtk_widget_get_next_sibling (child))
{ {
if (GTK_IS_NATIVE (child)) if (GTK_IS_POPOVER (child))
gtk_native_check_resize (GTK_NATIVE (child)); gtk_popover_present (GTK_POPOVER (child));
else if (GTK_IS_TEXT_HANDLE (child))
gtk_text_handle_present (GTK_TEXT_HANDLE (child));
else if (GTK_IS_TOOLTIP_WINDOW (child))
gtk_tooltip_window_present (GTK_TOOLTIP_WINDOW (child));
else if (GTK_IS_NATIVE (child))
g_warning ("Unable to present a to the layout manager unknown auxiliary child surface widget type %s",
G_OBJECT_TYPE_NAME (child));
} }
} }

View File

@ -319,7 +319,7 @@ gtk_menu_button_size_allocate (GtkWidget *widget,
&(GtkAllocation) { 0, 0, width, height }, &(GtkAllocation) { 0, 0, width, height },
baseline); baseline);
if (self->popover) if (self->popover)
gtk_native_check_resize (GTK_NATIVE (self->popover)); gtk_popover_present (GTK_POPOVER (self->popover));
} }
static gboolean static gboolean

View File

@ -24,6 +24,15 @@
#include "gdk/gdk-private.h" #include "gdk/gdk-private.h"
#include "gtkprivate.h" #include "gtkprivate.h"
#include "gtkintl.h" #include "gtkintl.h"
#include "gtkcssnodeprivate.h"
typedef struct _GtkNativePrivate
{
gulong update_handler_id;
gulong layout_handler_id;
} GtkNativePrivate;
static GQuark quark_gtk_native_private;
/** /**
* SECTION:gtknative * SECTION:gtknative
@ -55,7 +64,9 @@ gtk_native_default_get_surface_transform (GtkNative *self,
} }
static void static void
gtk_native_default_check_resize (GtkNative *self) gtk_native_default_layout (GtkNative *self,
int width,
int height)
{ {
} }
@ -64,7 +75,95 @@ gtk_native_default_init (GtkNativeInterface *iface)
{ {
iface->get_renderer = gtk_native_default_get_renderer; iface->get_renderer = gtk_native_default_get_renderer;
iface->get_surface_transform = gtk_native_default_get_surface_transform; iface->get_surface_transform = gtk_native_default_get_surface_transform;
iface->check_resize = gtk_native_default_check_resize; iface->layout = gtk_native_default_layout;
quark_gtk_native_private = g_quark_from_static_string ("gtk-native-private");
}
static void
frame_clock_update_cb (GdkFrameClock *clock,
GtkNative *native)
{
if (GTK_IS_ROOT (native))
gtk_css_node_validate (gtk_widget_get_css_node (GTK_WIDGET (native)));
}
static void
gtk_native_layout (GtkNative *self,
int width,
int height)
{
return GTK_NATIVE_GET_IFACE (self)->layout (self, width, height);
}
static void
surface_layout_cb (GdkSurface *surface,
int width,
int height,
GtkNative *native)
{
gtk_native_layout (native, width, height);
if (gtk_widget_needs_allocate (GTK_WIDGET (native)))
gtk_native_queue_relayout (native);
}
static void
verify_priv_unrealized (gpointer user_data)
{
GtkNativePrivate *priv = user_data;
g_warn_if_fail (priv->update_handler_id == 0);
g_warn_if_fail (priv->layout_handler_id == 0);
g_free (priv);
}
void
gtk_native_realize (GtkNative *self)
{
GdkSurface *surface;
GdkFrameClock *clock;
GtkNativePrivate *priv;
g_return_if_fail (g_object_get_qdata (G_OBJECT (self),
quark_gtk_native_private) == NULL);
surface = gtk_native_get_surface (self);
clock = gdk_surface_get_frame_clock (surface);
g_return_if_fail (clock != NULL);
priv = g_new0 (GtkNativePrivate, 1);
priv->update_handler_id = g_signal_connect_after (clock, "update",
G_CALLBACK (frame_clock_update_cb),
self);
priv->layout_handler_id = g_signal_connect (surface, "layout",
G_CALLBACK (surface_layout_cb),
self);
g_object_set_qdata_full (G_OBJECT (self),
quark_gtk_native_private,
priv,
verify_priv_unrealized);
}
void
gtk_native_unrealize (GtkNative *self)
{
GtkNativePrivate *priv;
GdkSurface *surface;
GdkFrameClock *clock;
priv = g_object_get_qdata (G_OBJECT (self), quark_gtk_native_private);
g_return_if_fail (priv != NULL);
surface = gtk_native_get_surface (self);
clock = gdk_surface_get_frame_clock (surface);
g_return_if_fail (clock != NULL);
g_clear_signal_handler (&priv->update_handler_id, clock);
g_clear_signal_handler (&priv->layout_handler_id, surface);
g_object_set_qdata (G_OBJECT (self), quark_gtk_native_private, NULL);
} }
/** /**
@ -120,23 +219,6 @@ gtk_native_get_surface_transform (GtkNative *self,
return GTK_NATIVE_GET_IFACE (self)->get_surface_transform (self, x, y); return GTK_NATIVE_GET_IFACE (self)->get_surface_transform (self, x, y);
} }
/**
* gtk_native_check_resize:
* @self: a #GtkNative
*
* Reposition and resize a #GtkNative.
*
* Widgets need to call this function on their attached
* native widgets when they receive a new size allocation.
*/
void
gtk_native_check_resize (GtkNative *self)
{
g_return_if_fail (GTK_IS_NATIVE (self));
GTK_NATIVE_GET_IFACE (self)->check_resize (self);
}
/** /**
* gtk_native_get_for_surface: * gtk_native_get_for_surface:
* @surface: a #GdkSurface * @surface: a #GdkSurface
@ -157,3 +239,19 @@ gtk_native_get_for_surface (GdkSurface *surface)
return NULL; return NULL;
} }
void
gtk_native_queue_relayout (GtkNative *self)
{
GtkWidget *widget = GTK_WIDGET (self);
GdkSurface *surface;
GdkFrameClock *clock;
surface = gtk_widget_get_surface (widget);
clock = gtk_widget_get_frame_clock (widget);
if (clock == NULL)
return;
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE);
gdk_surface_request_layout (surface);
}

View File

@ -34,13 +34,15 @@ G_BEGIN_DECLS
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
G_DECLARE_INTERFACE (GtkNative, gtk_native, GTK, NATIVE, GtkWidget) G_DECLARE_INTERFACE (GtkNative, gtk_native, GTK, NATIVE, GtkWidget)
GDK_AVAILABLE_IN_ALL
void gtk_native_realize (GtkNative *self);
GDK_AVAILABLE_IN_ALL
void gtk_native_unrealize (GtkNative *self);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GtkNative * gtk_native_get_for_surface (GdkSurface *surface); GtkNative * gtk_native_get_for_surface (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gtk_native_check_resize (GtkNative *self);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GdkSurface *gtk_native_get_surface (GtkNative *self); GdkSurface *gtk_native_get_surface (GtkNative *self);

View File

@ -23,9 +23,13 @@ struct _GtkNativeInterface
double *x, double *x,
double *y); double *y);
void (* check_resize) (GtkNative *self); void (* layout) (GtkNative *self,
int width,
int height);
}; };
void gtk_native_queue_relayout (GtkNative *native);
G_END_DECLS G_END_DECLS
#endif /* __GTK_NATIVE_PRIVATE_H__ */ #endif /* __GTK_NATIVE_PRIVATE_H__ */

View File

@ -4076,10 +4076,10 @@ gtk_places_sidebar_size_allocate (GtkWidget *widget,
baseline); baseline);
if (sidebar->popover) if (sidebar->popover)
gtk_native_check_resize (GTK_NATIVE (sidebar->popover)); gtk_popover_present (GTK_POPOVER (sidebar->popover));
if (sidebar->rename_popover) if (sidebar->rename_popover)
gtk_native_check_resize (GTK_NATIVE (sidebar->rename_popover)); gtk_popover_present (GTK_POPOVER (sidebar->rename_popover));
} }
static void static void

View File

@ -36,6 +36,7 @@
#include "gtkstack.h" #include "gtkstack.h"
#include "gtktypebuiltins.h" #include "gtktypebuiltins.h"
#include "gtknative.h" #include "gtknative.h"
#include "gtkpopover.h"
#else #else
#include <gtk/gtk.h> #include <gtk/gtk.h>
#endif #endif
@ -319,7 +320,7 @@ gtk_places_view_row_size_allocate (GtkWidget *widget,
GTK_WIDGET_CLASS (gtk_places_view_row_parent_class)->size_allocate (widget, width, height, baseline); GTK_WIDGET_CLASS (gtk_places_view_row_parent_class)->size_allocate (widget, width, height, baseline);
if (menu) if (menu)
gtk_native_check_resize (GTK_NATIVE (menu)); gtk_popover_present (GTK_POPOVER (menu));
} }
static void static void

View File

@ -419,11 +419,6 @@ update_popover_layout (GtkPopover *popover,
g_clear_pointer (&priv->arrow_render_node, gsk_render_node_unref); g_clear_pointer (&priv->arrow_render_node, gsk_render_node_unref);
} }
gtk_widget_allocate (GTK_WIDGET (popover),
gdk_surface_get_width (priv->surface),
gdk_surface_get_height (priv->surface),
-1, NULL);
gtk_widget_queue_draw (GTK_WIDGET (popover)); gtk_widget_queue_draw (GTK_WIDGET (popover));
} }
@ -582,10 +577,9 @@ present_popup (GtkPopover *popover)
return FALSE; return FALSE;
} }
static void void
gtk_popover_native_check_resize (GtkNative *native) gtk_popover_present (GtkPopover *popover)
{ {
GtkPopover *popover = GTK_POPOVER (native);
GtkWidget *widget = GTK_WIDGET (popover); GtkWidget *widget = GTK_WIDGET (popover);
if (!_gtk_widget_get_alloc_needed (widget)) if (!_gtk_widget_get_alloc_needed (widget))
@ -594,6 +588,61 @@ gtk_popover_native_check_resize (GtkNative *native)
present_popup (popover); present_popup (popover);
} }
static void
maybe_request_motion_event (GtkPopover *popover)
{
GtkWidget *widget = GTK_WIDGET (popover);
GtkRoot *root = gtk_widget_get_root (widget);
GdkSeat *seat;
GdkDevice *device;
GtkWidget *focus;
GdkSurface *focus_surface;
seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
if (!seat)
return;
device = gdk_seat_get_pointer (seat);
focus = gtk_window_lookup_pointer_focus_widget (GTK_WINDOW (root),
device, NULL);
if (!focus)
return;
if (!gtk_widget_is_ancestor (focus, GTK_WIDGET (popover)))
return;
focus_surface = gtk_native_get_surface (gtk_widget_get_native (focus));
gdk_surface_request_motion (focus_surface);
}
static void
gtk_popover_native_layout (GtkNative *native,
int width,
int height)
{
GtkPopover *popover = GTK_POPOVER (native);
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
GtkWidget *widget = GTK_WIDGET (popover);
update_popover_layout (popover, gdk_popup_layout_ref (priv->layout));
if (gtk_widget_needs_allocate (widget))
{
gtk_widget_allocate (widget, width, height, -1, NULL);
/* This fake motion event is needed for getting up to date pointer focus
* and coordinates when tho pointer didn't move but the layout changed
* within the popover.
*/
maybe_request_motion_event (popover);
}
else
{
gtk_widget_ensure_allocate (widget);
}
}
static gboolean static gboolean
gtk_popover_has_mnemonic_modifier_pressed (GtkPopover *popover) gtk_popover_has_mnemonic_modifier_pressed (GtkPopover *popover)
{ {
@ -736,13 +785,6 @@ surface_mapped_changed (GtkWidget *widget)
gtk_widget_set_visible (widget, gdk_surface_get_mapped (priv->surface)); gtk_widget_set_visible (widget, gdk_surface_get_mapped (priv->surface));
} }
static void
surface_size_changed (GtkWidget *widget,
guint width,
guint height)
{
}
static gboolean static gboolean
surface_render (GdkSurface *surface, surface_render (GdkSurface *surface,
cairo_region_t *region, cairo_region_t *region,
@ -761,16 +803,6 @@ surface_event (GdkSurface *surface,
return TRUE; return TRUE;
} }
static void
popup_layout_changed (GdkSurface *surface,
GtkWidget *widget)
{
GtkPopover *popover = GTK_POPOVER (widget);
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
update_popover_layout (popover, gdk_popup_layout_ref (priv->layout));
}
static void static void
gtk_popover_activate_default (GtkPopover *popover) gtk_popover_activate_default (GtkPopover *popover)
{ {
@ -887,14 +919,14 @@ gtk_popover_realize (GtkWidget *widget)
gdk_surface_set_widget (priv->surface, widget); gdk_surface_set_widget (priv->surface, widget);
g_signal_connect_swapped (priv->surface, "notify::mapped", G_CALLBACK (surface_mapped_changed), widget); g_signal_connect_swapped (priv->surface, "notify::mapped", G_CALLBACK (surface_mapped_changed), widget);
g_signal_connect_swapped (priv->surface, "size-changed", G_CALLBACK (surface_size_changed), widget);
g_signal_connect (priv->surface, "render", G_CALLBACK (surface_render), widget); g_signal_connect (priv->surface, "render", G_CALLBACK (surface_render), widget);
g_signal_connect (priv->surface, "event", G_CALLBACK (surface_event), widget); g_signal_connect (priv->surface, "event", G_CALLBACK (surface_event), widget);
g_signal_connect (priv->surface, "popup-layout-changed", G_CALLBACK (popup_layout_changed), widget);
GTK_WIDGET_CLASS (gtk_popover_parent_class)->realize (widget); GTK_WIDGET_CLASS (gtk_popover_parent_class)->realize (widget);
priv->renderer = gsk_renderer_new_for_surface (priv->surface); priv->renderer = gsk_renderer_new_for_surface (priv->surface);
gtk_native_realize (GTK_NATIVE (popover));
} }
static void static void
@ -903,16 +935,16 @@ gtk_popover_unrealize (GtkWidget *widget)
GtkPopover *popover = GTK_POPOVER (widget); GtkPopover *popover = GTK_POPOVER (widget);
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover); GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
gtk_native_unrealize (GTK_NATIVE (popover));
GTK_WIDGET_CLASS (gtk_popover_parent_class)->unrealize (widget); GTK_WIDGET_CLASS (gtk_popover_parent_class)->unrealize (widget);
gsk_renderer_unrealize (priv->renderer); gsk_renderer_unrealize (priv->renderer);
g_clear_object (&priv->renderer); g_clear_object (&priv->renderer);
g_signal_handlers_disconnect_by_func (priv->surface, surface_mapped_changed, widget); g_signal_handlers_disconnect_by_func (priv->surface, surface_mapped_changed, widget);
g_signal_handlers_disconnect_by_func (priv->surface, surface_size_changed, widget);
g_signal_handlers_disconnect_by_func (priv->surface, surface_render, widget); g_signal_handlers_disconnect_by_func (priv->surface, surface_render, widget);
g_signal_handlers_disconnect_by_func (priv->surface, surface_event, widget); g_signal_handlers_disconnect_by_func (priv->surface, surface_event, widget);
g_signal_handlers_disconnect_by_func (priv->surface, popup_layout_changed, widget);
gdk_surface_set_widget (priv->surface, NULL); gdk_surface_set_widget (priv->surface, NULL);
gdk_surface_destroy (priv->surface); gdk_surface_destroy (priv->surface);
g_clear_object (&priv->surface); g_clear_object (&priv->surface);
@ -1847,7 +1879,7 @@ gtk_popover_native_interface_init (GtkNativeInterface *iface)
iface->get_surface = gtk_popover_native_get_surface; iface->get_surface = gtk_popover_native_get_surface;
iface->get_renderer = gtk_popover_native_get_renderer; iface->get_renderer = gtk_popover_native_get_renderer;
iface->get_surface_transform = gtk_popover_native_get_surface_transform; iface->get_surface_transform = gtk_popover_native_get_surface_transform;
iface->check_resize = gtk_popover_native_check_resize; iface->layout = gtk_popover_native_layout;
} }
static GtkBuildableIface *parent_buildable_iface; static GtkBuildableIface *parent_buildable_iface;

View File

@ -121,6 +121,9 @@ GDK_AVAILABLE_IN_ALL
void gtk_popover_set_default_widget (GtkPopover *popover, void gtk_popover_set_default_widget (GtkPopover *popover,
GtkWidget *widget); GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_popover_present (GtkPopover *popover);
G_END_DECLS G_END_DECLS

View File

@ -320,7 +320,7 @@ gtk_popover_menu_bar_item_size_allocate (GtkWidget *widget,
&(GtkAllocation) { 0, 0, width, height }, &(GtkAllocation) { 0, 0, width, height },
baseline); baseline);
gtk_native_check_resize (GTK_NATIVE (item->popover)); gtk_popover_present (GTK_POPOVER (item->popover));
} }
static void static void

View File

@ -21,6 +21,7 @@
#include "gtkrootprivate.h" #include "gtkrootprivate.h"
#include "gtknative.h" #include "gtknative.h"
#include "gtknativeprivate.h"
#include "gtkcssnodeprivate.h" #include "gtkcssnodeprivate.h"
#include "gtkwidgetprivate.h" #include "gtkwidgetprivate.h"
#include "gdk/gdk-private.h" #include "gdk/gdk-private.h"
@ -43,9 +44,6 @@
* The obvious example of a #GtkRoot is #GtkWindow. * The obvious example of a #GtkRoot is #GtkWindow.
*/ */
static GQuark quark_restyle_pending;
static GQuark quark_resize_handler;
G_DEFINE_INTERFACE_WITH_CODE (GtkRoot, gtk_root, GTK_TYPE_WIDGET, G_DEFINE_INTERFACE_WITH_CODE (GtkRoot, gtk_root, GTK_TYPE_WIDGET,
g_type_interface_add_prerequisite (g_define_type_id, GTK_TYPE_NATIVE)) g_type_interface_add_prerequisite (g_define_type_id, GTK_TYPE_NATIVE))
@ -81,9 +79,6 @@ gtk_root_default_init (GtkRootInterface *iface)
iface->get_constraint_solver = gtk_root_default_get_constraint_solver; iface->get_constraint_solver = gtk_root_default_get_constraint_solver;
iface->get_focus = gtk_root_default_get_focus; iface->get_focus = gtk_root_default_get_focus;
iface->set_focus = gtk_root_default_set_focus; iface->set_focus = gtk_root_default_set_focus;
quark_restyle_pending = g_quark_from_static_string ("gtk-root-restyle-pending");
quark_resize_handler = g_quark_from_static_string ("gtk-root-resize-handler");
} }
/** /**
@ -161,117 +156,19 @@ gtk_root_get_focus (GtkRoot *self)
return GTK_ROOT_GET_IFACE (self)->get_focus (self); return GTK_ROOT_GET_IFACE (self)->get_focus (self);
} }
static gboolean
gtk_root_needs_layout (GtkRoot *self)
{
if (g_object_get_qdata (G_OBJECT (self), quark_restyle_pending))
return TRUE;
return gtk_widget_needs_allocate (GTK_WIDGET (self));
}
static void
gtk_root_layout_cb (GdkFrameClock *clock,
GtkRoot *self)
{
GtkWidget *widget = GTK_WIDGET (self);
/* We validate the style contexts in a single loop before even trying
* to handle resizes instead of doing validations inline.
* This is mostly necessary for compatibility reasons with old code,
* because both css_changed and size_allocate functions often change
* styles and so could cause infinite loops in this function.
*
* It's important to note that even an invalid style context returns
* sane values. So the result of an invalid style context will never be
* a program crash, but only a wrong layout or rendering.
*/
if (g_object_get_qdata (G_OBJECT (self), quark_restyle_pending))
{
g_object_set_qdata (G_OBJECT (self), quark_restyle_pending, NULL);
gtk_css_node_validate (gtk_widget_get_css_node (widget));
}
/* we may be invoked with a container_resize_queue of NULL, because
* queue_resize could have been adding an extra idle function while
* the queue still got processed. we better just ignore such case
* than trying to explicitly work around them with some extra flags,
* since it doesn't cause any actual harm.
*/
if (gtk_widget_needs_allocate (widget))
{
gtk_native_check_resize (GTK_NATIVE (self));
if (GTK_IS_WINDOW (widget))
{
GdkSeat *seat;
seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
if (seat)
{
GdkDevice *device;
GtkWidget *focus;
device = gdk_seat_get_pointer (seat);
focus = gtk_window_lookup_pointer_focus_widget (GTK_WINDOW (widget), device, NULL);
if (focus)
gdk_surface_request_motion (gtk_native_get_surface (gtk_widget_get_native (focus)));
}
}
}
if (!gtk_root_needs_layout (self))
gtk_root_stop_layout (self);
else
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
}
void void
gtk_root_start_layout (GtkRoot *self) gtk_root_start_layout (GtkRoot *self)
{ {
GdkFrameClock *clock; gtk_native_queue_relayout (GTK_NATIVE (self));
guint resize_handler;
if (g_object_get_qdata (G_OBJECT (self), quark_resize_handler))
return;
if (!gtk_root_needs_layout (self))
return;
clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
if (clock == NULL)
return;
resize_handler = g_signal_connect (clock, "layout",
G_CALLBACK (gtk_root_layout_cb), self);
g_object_set_qdata (G_OBJECT (self), quark_resize_handler, GINT_TO_POINTER (resize_handler));
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
} }
void void
gtk_root_stop_layout (GtkRoot *self) gtk_root_stop_layout (GtkRoot *self)
{ {
GdkFrameClock *clock;
guint resize_handler;
resize_handler = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (self), quark_resize_handler));
if (resize_handler == 0)
return;
clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
g_signal_handler_disconnect (clock, resize_handler);
g_object_set_qdata (G_OBJECT (self), quark_resize_handler, NULL);
} }
void void
gtk_root_queue_restyle (GtkRoot *self) gtk_root_queue_restyle (GtkRoot *self)
{ {
if (g_object_get_qdata (G_OBJECT (self), quark_restyle_pending))
return;
g_object_set_qdata (G_OBJECT (self), quark_restyle_pending, GINT_TO_POINTER (1));
gtk_root_start_layout (self); gtk_root_start_layout (self);
} }

View File

@ -1001,5 +1001,5 @@ gtk_scale_button_size_allocate (GtkWidget *widget,
&(GtkAllocation) { 0, 0, width, height }, &(GtkAllocation) { 0, 0, width, height },
baseline); baseline);
gtk_native_check_resize (GTK_NATIVE (priv->dock)); gtk_popover_present (GTK_POPOVER (priv->dock));
} }

View File

@ -2448,27 +2448,27 @@ gtk_text_size_allocate (GtkWidget *widget,
chooser = g_object_get_data (G_OBJECT (self), "gtk-emoji-chooser"); chooser = g_object_get_data (G_OBJECT (self), "gtk-emoji-chooser");
if (chooser) if (chooser)
gtk_native_check_resize (GTK_NATIVE (chooser)); gtk_popover_present (GTK_POPOVER (chooser));
gtk_text_update_handles (self); gtk_text_update_handles (self);
if (priv->emoji_completion) if (priv->emoji_completion)
gtk_native_check_resize (GTK_NATIVE (priv->emoji_completion)); gtk_popover_present (GTK_POPOVER (priv->emoji_completion));
if (priv->magnifier_popover) if (priv->magnifier_popover)
gtk_native_check_resize (GTK_NATIVE (priv->magnifier_popover)); gtk_popover_present (GTK_POPOVER (priv->magnifier_popover));
if (priv->popup_menu) if (priv->popup_menu)
gtk_native_check_resize (GTK_NATIVE (priv->popup_menu)); gtk_popover_present (GTK_POPOVER (priv->popup_menu));
if (priv->selection_bubble) if (priv->selection_bubble)
gtk_native_check_resize (GTK_NATIVE (priv->selection_bubble)); gtk_popover_present (GTK_POPOVER (priv->selection_bubble));
if (priv->text_handles[TEXT_HANDLE_CURSOR]) if (priv->text_handles[TEXT_HANDLE_CURSOR])
gtk_native_check_resize (GTK_NATIVE (priv->text_handles[TEXT_HANDLE_CURSOR])); gtk_text_handle_present (priv->text_handles[TEXT_HANDLE_CURSOR]);
if (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND]) if (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND])
gtk_native_check_resize (GTK_NATIVE (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND])); gtk_text_handle_present (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND]);
} }
static void static void

View File

@ -162,18 +162,12 @@ gtk_text_handle_present_surface (GtkTextHandle *handle)
MAX (req.height, 1), MAX (req.height, 1),
layout); layout);
gdk_popup_layout_unref (layout); gdk_popup_layout_unref (layout);
gtk_widget_allocate (widget,
gdk_surface_get_width (handle->surface),
gdk_surface_get_height (handle->surface),
-1, NULL);
} }
static void void
gtk_text_handle_native_check_resize (GtkNative *native) gtk_text_handle_present (GtkTextHandle *handle)
{ {
GtkTextHandle *handle = GTK_TEXT_HANDLE (native); GtkWidget *widget = GTK_WIDGET (handle);
GtkWidget *widget = GTK_WIDGET (native);
if (!_gtk_widget_get_alloc_needed (widget)) if (!_gtk_widget_get_alloc_needed (widget))
gtk_widget_ensure_allocate (widget); gtk_widget_ensure_allocate (widget);
@ -181,13 +175,26 @@ gtk_text_handle_native_check_resize (GtkNative *native)
gtk_text_handle_present_surface (handle); gtk_text_handle_present_surface (handle);
} }
static void
gtk_text_handle_native_layout (GtkNative *native,
int width,
int height)
{
GtkWidget *widget = GTK_WIDGET (native);
if (_gtk_widget_get_alloc_needed (widget))
gtk_widget_allocate (widget, width, height, -1, NULL);
else
gtk_widget_ensure_allocate (widget);
}
static void static void
gtk_text_handle_native_interface_init (GtkNativeInterface *iface) gtk_text_handle_native_interface_init (GtkNativeInterface *iface)
{ {
iface->get_surface = gtk_text_handle_native_get_surface; iface->get_surface = gtk_text_handle_native_get_surface;
iface->get_renderer = gtk_text_handle_native_get_renderer; iface->get_renderer = gtk_text_handle_native_get_renderer;
iface->get_surface_transform = gtk_text_handle_native_get_surface_transform; iface->get_surface_transform = gtk_text_handle_native_get_surface_transform;
iface->check_resize = gtk_text_handle_native_check_resize; iface->layout = gtk_text_handle_native_layout;
} }
static gboolean static gboolean
@ -240,6 +247,8 @@ gtk_text_handle_realize (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_text_handle_parent_class)->realize (widget); GTK_WIDGET_CLASS (gtk_text_handle_parent_class)->realize (widget);
handle->renderer = gsk_renderer_new_for_surface (handle->surface); handle->renderer = gsk_renderer_new_for_surface (handle->surface);
gtk_native_realize (GTK_NATIVE (handle));
} }
static void static void
@ -247,6 +256,8 @@ gtk_text_handle_unrealize (GtkWidget *widget)
{ {
GtkTextHandle *handle = GTK_TEXT_HANDLE (widget); GtkTextHandle *handle = GTK_TEXT_HANDLE (widget);
gtk_native_unrealize (GTK_NATIVE (handle));
GTK_WIDGET_CLASS (gtk_text_handle_parent_class)->unrealize (widget); GTK_WIDGET_CLASS (gtk_text_handle_parent_class)->unrealize (widget);
gsk_renderer_unrealize (handle->renderer); gsk_renderer_unrealize (handle->renderer);

View File

@ -35,6 +35,8 @@ typedef enum
GtkTextHandle * gtk_text_handle_new (GtkWidget *parent); GtkTextHandle * gtk_text_handle_new (GtkWidget *parent);
void gtk_text_handle_present (GtkTextHandle *handle);
void gtk_text_handle_set_role (GtkTextHandle *handle, void gtk_text_handle_set_role (GtkTextHandle *handle,
GtkTextHandleRole role); GtkTextHandleRole role);
GtkTextHandleRole gtk_text_handle_get_role (GtkTextHandle *handle); GtkTextHandleRole gtk_text_handle_get_role (GtkTextHandle *handle);

View File

@ -4528,22 +4528,22 @@ gtk_text_view_size_allocate (GtkWidget *widget,
chooser = g_object_get_data (G_OBJECT (text_view), "gtk-emoji-chooser"); chooser = g_object_get_data (G_OBJECT (text_view), "gtk-emoji-chooser");
if (chooser) if (chooser)
gtk_native_check_resize (GTK_NATIVE (chooser)); gtk_popover_present (GTK_POPOVER (chooser));
if (priv->magnifier_popover) if (priv->magnifier_popover)
gtk_native_check_resize (GTK_NATIVE (priv->magnifier_popover)); gtk_popover_present (GTK_POPOVER (priv->magnifier_popover));
if (priv->popup_menu) if (priv->popup_menu)
gtk_native_check_resize (GTK_NATIVE (priv->popup_menu)); gtk_popover_present (GTK_POPOVER (priv->popup_menu));
if (priv->text_handles[TEXT_HANDLE_CURSOR]) if (priv->text_handles[TEXT_HANDLE_CURSOR])
gtk_native_check_resize (GTK_NATIVE (priv->text_handles[TEXT_HANDLE_CURSOR])); gtk_text_handle_present (priv->text_handles[TEXT_HANDLE_CURSOR]);
if (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND]) if (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND])
gtk_native_check_resize (GTK_NATIVE (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND])); gtk_text_handle_present (priv->text_handles[TEXT_HANDLE_SELECTION_BOUND]);
if (priv->selection_bubble) if (priv->selection_bubble)
gtk_native_check_resize (GTK_NATIVE (priv->selection_bubble)); gtk_popover_present (GTK_POPOVER (priv->selection_bubble));
} }
static void static void

View File

@ -1024,7 +1024,7 @@ gtk_tooltip_maybe_allocate (GtkNative *native)
if (!tooltip || GTK_NATIVE (tooltip->native) != native) if (!tooltip || GTK_NATIVE (tooltip->native) != native)
return; return;
gtk_native_check_resize (GTK_NATIVE (tooltip->window)); gtk_tooltip_window_present (GTK_TOOLTIP_WINDOW (tooltip->window));
} }
void void

View File

@ -47,7 +47,6 @@ struct _GtkTooltipWindow
GdkSurface *surface; GdkSurface *surface;
GskRenderer *renderer; GskRenderer *renderer;
GdkToplevelState state;
GtkWidget *relative_to; GtkWidget *relative_to;
GdkRectangle rect; GdkRectangle rect;
GdkGravity rect_anchor; GdkGravity rect_anchor;
@ -139,11 +138,10 @@ gtk_tooltip_window_relayout (GtkTooltipWindow *window)
gdk_popup_layout_unref (layout); gdk_popup_layout_unref (layout);
} }
static void void
gtk_tooltip_window_native_check_resize (GtkNative *native) gtk_tooltip_window_present (GtkTooltipWindow *window)
{ {
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (native); GtkWidget *widget = GTK_WIDGET (window);
GtkWidget *widget = GTK_WIDGET (native);
if (!_gtk_widget_get_alloc_needed (widget)) if (!_gtk_widget_get_alloc_needed (widget))
{ {
@ -152,39 +150,39 @@ gtk_tooltip_window_native_check_resize (GtkNative *native)
else if (gtk_widget_get_visible (widget)) else if (gtk_widget_get_visible (widget))
{ {
gtk_tooltip_window_relayout (window); gtk_tooltip_window_relayout (window);
if (window->surface)
gtk_widget_allocate (GTK_WIDGET (window),
gdk_surface_get_width (window->surface),
gdk_surface_get_height (window->surface),
-1, NULL);
} }
} }
static void
gtk_tooltip_window_native_layout (GtkNative *native,
int width,
int height)
{
GtkWidget *widget = GTK_WIDGET (native);
if (gtk_widget_needs_allocate (widget))
gtk_widget_allocate (widget, width, height, -1, NULL);
else
gtk_widget_ensure_allocate (widget);
}
static void static void
gtk_tooltip_window_native_init (GtkNativeInterface *iface) gtk_tooltip_window_native_init (GtkNativeInterface *iface)
{ {
iface->get_surface = gtk_tooltip_window_native_get_surface; iface->get_surface = gtk_tooltip_window_native_get_surface;
iface->get_renderer = gtk_tooltip_window_native_get_renderer; iface->get_renderer = gtk_tooltip_window_native_get_renderer;
iface->get_surface_transform = gtk_tooltip_window_native_get_surface_transform; iface->get_surface_transform = gtk_tooltip_window_native_get_surface_transform;
iface->check_resize = gtk_tooltip_window_native_check_resize; iface->layout = gtk_tooltip_window_native_layout;
} }
static void static void
surface_state_changed (GtkWidget *widget) mapped_changed (GdkSurface *surface,
GParamSpec *pspec,
GtkWidget *widget)
{ {
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget); if (!gdk_surface_get_mapped (surface))
GdkToplevelState new_surface_state; gtk_widget_hide (widget);
GdkToplevelState changed_mask;
new_surface_state = gdk_toplevel_get_state (GDK_TOPLEVEL (window->surface));
changed_mask = new_surface_state ^ window->state;
window->state = new_surface_state;
if (changed_mask & GDK_TOPLEVEL_STATE_WITHDRAWN)
{
if (window->state & GDK_TOPLEVEL_STATE_WITHDRAWN)
gtk_widget_hide (widget);
}
} }
static gboolean static gboolean
@ -216,13 +214,15 @@ gtk_tooltip_window_realize (GtkWidget *widget)
gdk_surface_set_widget (window->surface, widget); gdk_surface_set_widget (window->surface, widget);
g_signal_connect_swapped (window->surface, "notify::state", G_CALLBACK (surface_state_changed), widget); g_signal_connect (window->surface, "notify::mapped", G_CALLBACK (mapped_changed), widget);
g_signal_connect (window->surface, "render", G_CALLBACK (surface_render), widget); g_signal_connect (window->surface, "render", G_CALLBACK (surface_render), widget);
g_signal_connect (window->surface, "event", G_CALLBACK (surface_event), widget); g_signal_connect (window->surface, "event", G_CALLBACK (surface_event), widget);
GTK_WIDGET_CLASS (gtk_tooltip_window_parent_class)->realize (widget); GTK_WIDGET_CLASS (gtk_tooltip_window_parent_class)->realize (widget);
window->renderer = gsk_renderer_new_for_surface (window->surface); window->renderer = gsk_renderer_new_for_surface (window->surface);
gtk_native_realize (GTK_NATIVE (window));
} }
static void static void
@ -230,12 +230,14 @@ gtk_tooltip_window_unrealize (GtkWidget *widget)
{ {
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget); GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget);
gtk_native_unrealize (GTK_NATIVE (window));
GTK_WIDGET_CLASS (gtk_tooltip_window_parent_class)->unrealize (widget); GTK_WIDGET_CLASS (gtk_tooltip_window_parent_class)->unrealize (widget);
gsk_renderer_unrealize (window->renderer); gsk_renderer_unrealize (window->renderer);
g_clear_object (&window->renderer); g_clear_object (&window->renderer);
g_signal_handlers_disconnect_by_func (window->surface, surface_state_changed, widget); g_signal_handlers_disconnect_by_func (window->surface, mapped_changed, widget);
g_signal_handlers_disconnect_by_func (window->surface, surface_render, widget); g_signal_handlers_disconnect_by_func (window->surface, surface_render, widget);
g_signal_handlers_disconnect_by_func (window->surface, surface_event, widget); g_signal_handlers_disconnect_by_func (window->surface, surface_event, widget);
gdk_surface_set_widget (window->surface, NULL); gdk_surface_set_widget (window->surface, NULL);
@ -340,7 +342,7 @@ gtk_tooltip_window_show (GtkWidget *widget)
{ {
_gtk_widget_set_visible_flag (widget, TRUE); _gtk_widget_set_visible_flag (widget, TRUE);
gtk_widget_realize (widget); gtk_widget_realize (widget);
gtk_tooltip_window_native_check_resize (GTK_NATIVE (widget)); gtk_tooltip_window_present (GTK_TOOLTIP_WINDOW (widget));
gtk_widget_map (widget); gtk_widget_map (widget);
} }

View File

@ -37,6 +37,8 @@ G_DECLARE_FINAL_TYPE (GtkTooltipWindow, gtk_tooltip_window, GTK, TOOLTIP_WINDOW,
GtkWidget * gtk_tooltip_window_new (void); GtkWidget * gtk_tooltip_window_new (void);
void gtk_tooltip_window_present (GtkTooltipWindow *window);
void gtk_tooltip_window_set_label_markup (GtkTooltipWindow *window, void gtk_tooltip_window_set_label_markup (GtkTooltipWindow *window,
const char *markup); const char *markup);
void gtk_tooltip_window_set_label_text (GtkTooltipWindow *window, void gtk_tooltip_window_set_label_text (GtkTooltipWindow *window,

View File

@ -2654,7 +2654,7 @@ gtk_tree_view_size_allocate (GtkWidget *widget,
} }
if (priv->search_popover) if (priv->search_popover)
gtk_native_check_resize (GTK_NATIVE (priv->search_popover)); gtk_popover_present (GTK_POPOVER (priv->search_popover));
} }
/* Grabs the focus and unsets the GTK_TREE_VIEW_DRAW_KEYFOCUS flag */ /* Grabs the focus and unsets the GTK_TREE_VIEW_DRAW_KEYFOCUS flag */

View File

@ -56,6 +56,7 @@
#include "gtkrenderbackgroundprivate.h" #include "gtkrenderbackgroundprivate.h"
#include "gtkrenderborderprivate.h" #include "gtkrenderborderprivate.h"
#include "gtkrootprivate.h" #include "gtkrootprivate.h"
#include "gtknativeprivate.h"
#include "gtkscrollable.h" #include "gtkscrollable.h"
#include "gtksettingsprivate.h" #include "gtksettingsprivate.h"
#include "gtkshortcut.h" #include "gtkshortcut.h"
@ -3243,7 +3244,7 @@ gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget,
} }
} }
static GdkSurface * GdkSurface *
gtk_widget_get_surface (GtkWidget *widget) gtk_widget_get_surface (GtkWidget *widget)
{ {
GtkNative *native = gtk_widget_get_native (widget); GtkNative *native = gtk_widget_get_native (widget);
@ -10325,9 +10326,11 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
if (!priv->visible) if (!priv->visible)
break; break;
if (GTK_IS_NATIVE (widget))
gtk_native_queue_relayout (GTK_NATIVE (widget));
if (!priv->parent && GTK_IS_ROOT (widget)) if (!priv->parent && GTK_IS_ROOT (widget))
{ {
gtk_root_start_layout (GTK_ROOT (widget));
break; break;
} }

View File

@ -229,6 +229,8 @@ void gtk_widget_ensure_resize (GtkWidget *widget);
void gtk_widget_ensure_allocate (GtkWidget *widget); void gtk_widget_ensure_allocate (GtkWidget *widget);
void _gtk_widget_scale_changed (GtkWidget *widget); void _gtk_widget_scale_changed (GtkWidget *widget);
GdkSurface * gtk_widget_get_surface (GtkWidget *widget);
void gtk_widget_render (GtkWidget *widget, void gtk_widget_render (GtkWidget *widget,
GdkSurface *surface, GdkSurface *surface,
const cairo_region_t *region); const cairo_region_t *region);

File diff suppressed because it is too large Load Diff

View File

@ -215,14 +215,6 @@ GDK_AVAILABLE_IN_ALL
void gtk_window_get_default_size (GtkWindow *window, void gtk_window_get_default_size (GtkWindow *window,
int *width, int *width,
int *height); int *height);
GDK_AVAILABLE_IN_ALL
void gtk_window_resize (GtkWindow *window,
int width,
int height);
GDK_AVAILABLE_IN_ALL
void gtk_window_get_size (GtkWindow *window,
int *width,
int *height);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GtkWindowGroup *gtk_window_get_group (GtkWindow *window); GtkWindowGroup *gtk_window_get_group (GtkWindow *window);
@ -251,6 +243,9 @@ GtkWidget *gtk_window_get_titlebar (GtkWindow *window);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
gboolean gtk_window_is_maximized (GtkWindow *window); gboolean gtk_window_is_maximized (GtkWindow *window);
GDK_AVAILABLE_IN_ALL
gboolean gtk_window_is_fullscreen (GtkWindow *window);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
void gtk_window_destroy (GtkWindow *window); void gtk_window_destroy (GtkWindow *window);

View File

@ -377,7 +377,7 @@ window_notify_cb (GtkWindowControls *self,
{ {
if (pspec->name == I_("deletable") || if (pspec->name == I_("deletable") ||
pspec->name == I_("icon-name") || pspec->name == I_("icon-name") ||
pspec->name == I_("is-maximized") || pspec->name == I_("maximized") ||
pspec->name == I_("modal") || pspec->name == I_("modal") ||
pspec->name == I_("resizable") || pspec->name == I_("resizable") ||
pspec->name == I_("scale-factor") || pspec->name == I_("scale-factor") ||

View File

@ -455,6 +455,15 @@ value_is_default (Element *element,
ret = g_value_get_boolean (&value) == default_value; ret = g_value_get_boolean (&value) == default_value;
} }
else if (pspec->owner_type == GTK_TYPE_WINDOW &&
(g_str_equal (pspec->name, "default-width") ||
g_str_equal (pspec->name, "default-height")))
{
int default_size;
default_size = g_value_get_int (&value);
ret = default_size <= 0;
}
else else
ret = g_param_value_defaults (pspec, &value); ret = g_param_value_defaults (pspec, &value);
} }

View File

@ -123,17 +123,16 @@ on_frame (double progress)
window_height = HEIGHT + jitter; window_height = HEIGHT + jitter;
} }
gtk_window_resize (GTK_WINDOW (window), gtk_window_set_default_size (GTK_WINDOW (window),
window_width, window_height); window_width, window_height);
gtk_widget_queue_draw (window); gtk_widget_queue_draw (window);
} }
static gboolean static gboolean
tick_callback (GtkWidget *widget, resize_idle (gpointer user_data)
GdkFrameClock *frame_clock,
gpointer user_data)
{ {
GdkFrameClock *frame_clock = user_data;
gint64 frame_time = gdk_frame_clock_get_frame_time (frame_clock); gint64 frame_time = gdk_frame_clock_get_frame_time (frame_clock);
double scaled_time; double scaled_time;
@ -143,6 +142,16 @@ tick_callback (GtkWidget *widget,
scaled_time = (frame_time - start_frame_time) / (CYCLE_TIME * 1000000); scaled_time = (frame_time - start_frame_time) / (CYCLE_TIME * 1000000);
on_frame (scaled_time - floor (scaled_time)); on_frame (scaled_time - floor (scaled_time));
return G_SOURCE_REMOVE;
}
static gboolean
tick_callback (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
g_idle_add (resize_idle, frame_clock);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }

View File

@ -239,9 +239,9 @@ main (int argc, char **argv)
} }
gsk_render_node_get_bounds (GTK_NODE_VIEW (nodeview)->node, &node_bounds); gsk_render_node_get_bounds (GTK_NODE_VIEW (nodeview)->node, &node_bounds);
gtk_window_resize (GTK_WINDOW (window), gtk_window_set_default_size (GTK_WINDOW (window),
MAX (600, node_bounds.size.width), MAX (600, node_bounds.size.width),
MAX (500, node_bounds.size.height)); MAX (500, node_bounds.size.height));
g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done); g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
gtk_widget_show (window); gtk_widget_show (window);

View File

@ -4531,8 +4531,6 @@ surface_state_callback (GdkSurface *window,
new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (window)); new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (window));
msg = g_strconcat ((const char *)g_object_get_data (G_OBJECT (label), "title"), ": ", msg = g_strconcat ((const char *)g_object_get_data (G_OBJECT (label), "title"), ": ",
(new_state & GDK_TOPLEVEL_STATE_WITHDRAWN) ?
"withdrawn" : "not withdrawn", ", ",
(new_state & GDK_TOPLEVEL_STATE_MINIMIZED) ? (new_state & GDK_TOPLEVEL_STATE_MINIMIZED) ?
"minimized" : "not minimized", ", ", "minimized" : "not minimized", ", ",
(new_state & GDK_TOPLEVEL_STATE_STICKY) ? (new_state & GDK_TOPLEVEL_STATE_STICKY) ?
@ -4775,17 +4773,6 @@ get_ints (GtkWidget *window,
*b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2)); *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
} }
static void
set_size_callback (GtkWidget *widget,
gpointer data)
{
int w, h;
get_ints (data, &w, &h);
gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
}
static void static void
unset_default_size_callback (GtkWidget *widget, unset_default_size_callback (GtkWidget *widget,
gpointer data) gpointer data)
@ -4891,13 +4878,6 @@ window_controls (GtkWidget *window)
G_CONNECT_SWAPPED); G_CONNECT_SWAPPED);
gtk_box_append (GTK_BOX (vbox), button); gtk_box_append (GTK_BOX (vbox), button);
button = gtk_button_new_with_label ("Resize");
g_signal_connect (button,
"clicked",
G_CALLBACK (set_size_callback),
control_window);
gtk_box_append (GTK_BOX (vbox), button);
button = gtk_button_new_with_label ("Set default size"); button = gtk_button_new_with_label ("Set default size");
g_signal_connect (button, g_signal_connect (button,
"clicked", "clicked",

View File

@ -46,7 +46,7 @@ int main (int argc, char **argv)
gtk_init (); gtk_init ();
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_resize (GTK_WINDOW (window), 400, 300); gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
grid = gtk_grid_new (); grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 12); gtk_grid_set_row_spacing (GTK_GRID (grid), 12);

View File

@ -8,14 +8,27 @@ static GtkWidget *default_width_spin;
static GtkWidget *default_height_spin; static GtkWidget *default_height_spin;
static GtkWidget *resizable_check; static GtkWidget *resizable_check;
static void static gboolean
size_changed_cb (GdkSurface *surface, int width, int height, GtkLabel *label) set_label_idle (gpointer user_data)
{ {
GtkLabel *label = user_data;
GtkNative *native = gtk_widget_get_native (GTK_WIDGET (label));
GdkSurface *surface = gtk_native_get_surface (native);
char *str; char *str;
str = g_strdup_printf ("%d x %d", width, height); str = g_strdup_printf ("%d x %d",
gdk_surface_get_width (surface),
gdk_surface_get_height (surface));
gtk_label_set_label (label, str); gtk_label_set_label (label, str);
g_free (str); g_free (str);
return G_SOURCE_REMOVE;
}
static void
layout_cb (GdkSurface *surface, int width, int height, GtkLabel *label)
{
g_idle_add (set_label_idle, label);
} }
static void static void
@ -63,8 +76,8 @@ show_dialog (void)
gtk_dialog_add_action_widget (GTK_DIALOG (dialog), label, GTK_RESPONSE_HELP); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), label, GTK_RESPONSE_HELP);
gtk_widget_realize (dialog); gtk_widget_realize (dialog);
g_signal_connect (gtk_native_get_surface (GTK_NATIVE (dialog)), "size-changed", g_signal_connect (gtk_native_get_surface (GTK_NATIVE (dialog)), "layout",
G_CALLBACK (size_changed_cb), label); G_CALLBACK (layout_cb), label);
g_signal_connect (dialog, "response", g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), G_CALLBACK (gtk_window_destroy),
NULL); NULL);

View File

@ -4691,7 +4691,6 @@ specific_append_after_collapse (void)
window = gtk_window_new (); window = gtk_window_new ();
tree_view = gtk_tree_view_new_with_model (sort); tree_view = gtk_tree_view_new_with_model (sort);
gtk_window_set_child (GTK_WINDOW (window), tree_view); gtk_window_set_child (GTK_WINDOW (window), tree_view);
gtk_widget_realize (tree_view);
while (g_main_context_pending (NULL)) while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE); g_main_context_iteration (NULL, TRUE);
@ -4811,7 +4810,6 @@ specific_sort_filter_remove_node (void)
window = gtk_window_new (); window = gtk_window_new ();
tree_view = gtk_tree_view_new_with_model (filter); tree_view = gtk_tree_view_new_with_model (filter);
gtk_window_set_child (GTK_WINDOW (window), tree_view); gtk_window_set_child (GTK_WINDOW (window), tree_view);
gtk_widget_realize (tree_view);
while (g_main_context_pending (NULL)) while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE); g_main_context_iteration (NULL, TRUE);

View File

@ -524,7 +524,8 @@ test_type (gconstpointer data)
g_str_equal (pspec->name, "has-default") || g_str_equal (pspec->name, "has-default") ||
g_str_equal (pspec->name, "is-focus") || g_str_equal (pspec->name, "is-focus") ||
g_str_equal (pspec->name, "hexpand") || g_str_equal (pspec->name, "hexpand") ||
g_str_equal (pspec->name, "vexpand"))) g_str_equal (pspec->name, "vexpand") ||
g_str_equal (pspec->name, "visible")))
continue; continue;
if (g_type_is_a (type, GTK_TYPE_ACCESSIBLE) && if (g_type_is_a (type, GTK_TYPE_ACCESSIBLE) &&

View File

@ -147,69 +147,6 @@ test_default_size (void)
gtk_window_destroy (GTK_WINDOW (window)); gtk_window_destroy (GTK_WINDOW (window));
} }
static void
test_resize (void)
{
GtkWidget *window;
GtkWidget *da;
int w, h;
gboolean done;
window = gtk_window_new ();
if (interactive)
{
GtkEventController *controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed", G_CALLBACK (on_keypress), window);
gtk_widget_add_controller (window, controller);
}
da = gtk_drawing_area_new ();
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), on_draw, NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), da);
/* test that resize before show overrides default size */
gtk_window_set_default_size (GTK_WINDOW (window), 500, 500);
gtk_window_resize (GTK_WINDOW (window), 1, 1);
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
g_assert_cmpint (w, ==, 1);
g_assert_cmpint (h, ==, 1);
gtk_window_resize (GTK_WINDOW (window), 400, 200);
gtk_widget_show (window);
done = FALSE;
if (!interactive)
g_timeout_add (200, stop_main, &done);
while (!done)
g_main_context_iteration (NULL, TRUE);
/* test that resize before show works */
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
g_assert_cmpint (w, ==, 400);
g_assert_cmpint (h, ==, 200);
/* test that resize after show works, both
* for making things bigger and for making things
* smaller
*/
gtk_window_resize (GTK_WINDOW (window), 200, 400);
done = FALSE;
if (!interactive)
g_timeout_add (200, stop_main, &done);
while (!done)
g_main_context_iteration (NULL, TRUE);
gtk_window_get_size (GTK_WINDOW (window), &w, &h);
g_assert_cmpint (w, ==, 200);
g_assert_cmpint (h, ==, 400);
gtk_window_destroy (GTK_WINDOW (window));
}
static void static void
test_resize_popup (void) test_resize_popup (void)
{ {
@ -220,7 +157,7 @@ test_resize_popup (void)
/* testcase for the dnd window */ /* testcase for the dnd window */
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_decorated (GTK_WINDOW (window), FALSE); gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
gtk_window_resize (GTK_WINDOW (window), 1, 1); gtk_window_set_default_size (GTK_WINDOW (window), 1, 1);
gtk_window_get_size (GTK_WINDOW (window), &w, &h); gtk_window_get_size (GTK_WINDOW (window), &w, &h);
g_assert_cmpint (w, ==, 1); g_assert_cmpint (w, ==, 1);
g_assert_cmpint (h, ==, 1); g_assert_cmpint (h, ==, 1);
@ -304,7 +241,6 @@ main (int argc, char *argv[])
} }
g_test_add_func ("/window/default-size", test_default_size); g_test_add_func ("/window/default-size", test_default_size);
g_test_add_func ("/window/resize", test_resize);
g_test_add_func ("/window/resize-popup", test_resize_popup); g_test_add_func ("/window/resize-popup", test_resize_popup);
g_test_add_func ("/window/show-hide", test_show_hide); g_test_add_func ("/window/show-hide", test_show_hide);

View File

@ -439,8 +439,6 @@ testdata = [
'window-default-size.ui', 'window-default-size.ui',
'window-height-for-width.ref.ui', 'window-height-for-width.ref.ui',
'window-height-for-width.ui', 'window-height-for-width.ui',
'window-show-contents-on-map.ref.ui',
'window-show-contents-on-map.ui',
] ]
# These need to be fixed but the issue hasn't been tracked down. # These need to be fixed but the issue hasn't been tracked down.

View File

@ -37,6 +37,7 @@
<object class="GtkWindow" id="window1"> <object class="GtkWindow" id="window1">
<child> <child>
<object class="GtkTextView" id="textview1"> <object class="GtkTextView" id="textview1">
<property name="cursor_visible">false</property>
<property name="buffer">textbuffer1</property> <property name="buffer">textbuffer1</property>
<signal name="map" handler="reftest:apply_tags_red_blue" swapped="no"/> <signal name="map" handler="reftest:apply_tags_red_blue" swapped="no"/>
</object> </object>

View File

@ -37,6 +37,7 @@
<object class="GtkWindow" id="window1"> <object class="GtkWindow" id="window1">
<child> <child>
<object class="GtkTextView" id="textview1"> <object class="GtkTextView" id="textview1">
<property name="cursor_visible">false</property>
<property name="buffer">textbuffer1</property> <property name="buffer">textbuffer1</property>
<signal name="map" handler="reftest:apply_tags_blue" swapped="no"/> <signal name="map" handler="reftest:apply_tags_blue" swapped="no"/>
</object> </object>

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window1">
<property name="width_request">200</property>
<property name="height_request">200</property>
<property name="decorated">0</property>
<child>
<object class="GtkLabel" id="label1">
<property name="label" translatable="yes">This label is only shown when the window is mapped. So the window does its first size allocation without the label being visible and has to resize.</property>
<property name="wrap">1</property>
<property name="width_chars">20</property>
<property name="max_width_chars">20</property>
</object>
</child>
</object>
</interface>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window1">
<property name="decorated">0</property>
<signal name="map" handler="gtk_widget_show" object="label1" after="yes" swapped="yes"/>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">0</property>
<property name="label" translatable="yes">This label is only shown when the window is mapped. So the window does its first size allocation without the label being visible and has to resize.</property>
<property name="width_chars">20</property>
<property name="wrap">1</property>
</object>
</child>
</object>
</interface>