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);
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

View File

@ -97,9 +97,9 @@ demo3_widget_size_allocate (GtkWidget *widget,
/* 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
* gtk_native_check_resize().
* gtk_popover_present().
*/
gtk_native_check_resize (GTK_NATIVE (self->menu));
gtk_popover_present (GTK_POPOVER (self->menu));
}
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_queue_resize (self->popup);
gtk_native_check_resize (GTK_NATIVE (self->popup));
gtk_popover_present (GTK_POPOVER (self->popup));
}
static gboolean

View File

@ -203,7 +203,6 @@ gdk_surface_get_cursor
gdk_surface_set_input_region
gdk_surface_get_width
gdk_surface_get_height
gdk_surface_set_shadow_width
gdk_surface_get_device_position
GdkModifierType
GDK_MODIFIER_MASK
@ -529,7 +528,6 @@ GDK_IS_EVENT
gdk_event_get_type
gdk_event_sequence_get_type
gdk_button_event_get_type
gdk_configure_event_get_type
gdk_crossing_event_get_type
gdk_delete_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_is_active
gtk_window_is_maximized
gtk_window_is_fullscreen
gtk_window_get_toplevels
gtk_window_list_toplevels
gtk_window_get_focus
@ -4618,12 +4619,10 @@ gtk_window_get_default_size
gtk_window_get_destroy_with_parent
gtk_window_get_icon_name
gtk_window_get_modal
gtk_window_get_size
gtk_window_get_title
gtk_window_get_transient_for
gtk_window_get_group
gtk_window_has_group
gtk_window_resize
gtk_window_set_default_icon_name
gtk_window_set_icon_name
gtk_window_set_auto_startup_notification
@ -6116,6 +6115,7 @@ GtkPopover
gtk_popover_new
gtk_popover_popup
gtk_popover_popdown
gtk_popover_present
gtk_popover_set_child
gtk_popover_get_child
gtk_popover_set_pointing_to
@ -6973,7 +6973,6 @@ GtkNative
gtk_native_get_for_surface
gtk_native_get_surface
gtk_native_get_renderer
gtk_native_check_resize
gtk_native_get_surface_transform
<SUBSECTION Private>

View File

@ -165,7 +165,7 @@ for this change.
| ::key-release-event | #GtkEventControllerKey |
| ::enter-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-out-event | #GtkEventControllerFocus |
| ::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_begin_resize_drag(), gtk_window_begin_move_drag().
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()).
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
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)
- 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():
- has no effect after the window has been mapped the first time,
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 -1 to unset the default size
- clamped to geometry hints
- gtk_window_resize() overrides it
- causes notifies on default_width, default_height properties
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));
if (surface)
{
event = gdk_configure_event_new (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);
gdk_surface_request_layout (surface);
if (surface->resize_count >= 1)
{

View File

@ -558,6 +558,7 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
int height,
GdkPopupLayout *layout)
{
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkMonitor *monitor;
GdkRectangle bounds;
GdkRectangle final_rect;
@ -570,6 +571,10 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface,
width,
height,
impl->shadow_left,
impl->shadow_right,
impl->shadow_top,
impl->shadow_bottom,
monitor,
&bounds,
layout,
@ -596,7 +601,7 @@ gdk_broadway_surface_layout_popup (GdkSurface *surface,
static void
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_surface_invalidate_rect (surface, NULL);
}
@ -1516,7 +1521,7 @@ show_surface (GdkSurface *surface)
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
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);
@ -1524,11 +1529,12 @@ show_surface (GdkSurface *surface)
gdk_surface_invalidate_rect (surface, NULL);
}
static gboolean
static void
gdk_broadway_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
@ -1582,9 +1588,15 @@ gdk_broadway_toplevel_present (GdkToplevel *toplevel,
else
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

View File

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

View File

@ -15,9 +15,6 @@ gboolean gdk_device_grab_info (GdkDisplay *display,
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);
void gdk_display_set_double_click_time (GdkDisplay *display,

View File

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

View File

@ -430,7 +430,6 @@ static void
gdk_event_init_types_once (void)
{
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_DELETE_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 */
static void

View File

@ -106,7 +106,6 @@ typedef struct _GdkEventSequence GdkEventSequence;
typedef struct _GdkEvent GdkEvent;
#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_DELETE_EVENT (gdk_delete_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())
typedef struct _GdkButtonEvent GdkButtonEvent;
typedef struct _GdkConfigureEvent GdkConfigureEvent;
typedef struct _GdkCrossingEvent GdkCrossingEvent;
typedef struct _GdkDeleteEvent GdkDeleteEvent;
typedef struct _GdkDNDEvent GdkDNDEvent;
@ -148,7 +146,6 @@ typedef struct _GdkTouchpadEvent GdkTouchpadEvent;
* @GDK_ENTER_NOTIFY: the pointer has entered the surface.
* @GDK_LEAVE_NOTIFY: the pointer has 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
* surface (e.g. a touchscreen or graphics tablet).
* @GDK_PROXIMITY_OUT: an input device has moved out of contact with a sensing
@ -188,7 +185,6 @@ typedef enum
GDK_ENTER_NOTIFY,
GDK_LEAVE_NOTIFY,
GDK_FOCUS_CHANGE,
GDK_CONFIGURE,
GDK_PROXIMITY_IN,
GDK_PROXIMITY_OUT,
GDK_DRAG_ENTER,
@ -429,12 +425,6 @@ GdkNotifyType gdk_crossing_event_get_detail (GdkEvent *event);
GDK_AVAILABLE_IN_ALL
gboolean gdk_crossing_event_get_focus (GdkEvent *event);
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;
GDK_AVAILABLE_IN_ALL
GdkTouchpadGesturePhase

View File

@ -322,25 +322,6 @@ struct _GdkFocusEvent
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:
* @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_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_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_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.

View File

@ -38,15 +38,6 @@
G_DEFINE_INTERFACE (GdkPopup, gdk_popup, GDK_TYPE_SURFACE)
enum
{
POPUP_LAYOUT_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS] = { 0 };
static gboolean
gdk_popup_default_present (GdkPopup *popup,
int width,
@ -101,25 +92,6 @@ gdk_popup_default_init (GdkPopupInterface *iface)
P_("Whether to hide on outside clicks"),
FALSE,
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,
* otherwise it will change position according to @layout.
*
* After calling this function, the result of the layout can be queried
* using gdk_popup_get_position_x(), gdk_popup_get_position_y(),
* gdk_surface_get_width(), gdk_surface_get_height(),
* gdk_popup_get_rect_anchor() and gdk_popup_get_surface_anchor().
* After calling this function, the result should be handled in response
* to the #GdkSurface::layout signal being emitted. The resulting popup
* position can be queried using gdk_popup_get_position_x(),
* 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
* hidden if the @popup was set to autohide.
* Presenting may fail, for example if the @popup is 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.
*/
@ -164,7 +139,7 @@ gdk_popup_present (GdkPopup *popup,
* Gets the current popup surface anchor.
*
* 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
*/
@ -183,7 +158,7 @@ gdk_popup_get_surface_anchor (GdkPopup *popup)
* Gets the current popup rectangle anchor.
*
* 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
*/

View File

@ -76,8 +76,7 @@
*/
enum {
POPUP_LAYOUT_CHANGED,
SIZE_CHANGED,
LAYOUT,
RENDER,
EVENT,
ENTER_MONITOR,
@ -115,6 +114,9 @@ static void update_cursor (GdkDisplay *display,
static void gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock);
static void gdk_surface_queue_set_is_mapped (GdkSurface *surface,
gboolean is_mapped);
static guint signals[LAST_SIGNAL] = { 0 };
static GParamSpec *properties[LAST_PROP] = { NULL, };
@ -285,6 +287,10 @@ void
gdk_surface_layout_popup_helper (GdkSurface *surface,
int width,
int height,
int shadow_left,
int shadow_right,
int shadow_top,
int shadow_bottom,
GdkMonitor *monitor,
GdkRectangle *bounds,
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);
anchor_hints = gdk_popup_layout_get_anchor_hints (layout);
final_rect.width = width - surface->shadow_left - surface->shadow_right;
final_rect.height = height - surface->shadow_top - surface->shadow_bottom;
final_rect.width = width - shadow_left - shadow_right;
final_rect.height = height - shadow_top - shadow_bottom;
final_rect.x = maybe_flip_position (bounds->x,
bounds->width,
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.x -= surface->shadow_left;
final_rect.y -= surface->shadow_top;
final_rect.width += surface->shadow_left + surface->shadow_right;
final_rect.height += surface->shadow_top + surface->shadow_bottom;
final_rect.x -= shadow_left;
final_rect.y -= shadow_top;
final_rect.width += shadow_left + shadow_right;
final_rect.height += shadow_top + shadow_bottom;
gdk_surface_get_origin (surface->parent, &x, &y);
final_rect.x -= x;
@ -469,7 +475,7 @@ gdk_surface_init (GdkSurface *surface)
{
/* 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->width = 1;
surface->height = 1;
@ -548,18 +554,19 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
g_object_class_install_properties (object_class, LAST_PROP, properties);
/**
* GdkSurface::size-changed:
* GdkSurface::layout:
* @surface: the #GdkSurface
* @width: the new width
* @height: the new height
* @width: the current width
* @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
* device pixels (see gdk_surface_get_scale_factor()).
*/
signals[SIZE_CHANGED] =
g_signal_new (g_intern_static_string ("size-changed"),
signals[LAYOUT] =
g_signal_new (g_intern_static_string ("layout"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
0,
@ -919,7 +926,10 @@ _gdk_surface_destroy_hierarchy (GdkSurface *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_remove_from_pointer_info (surface, surface->display);
@ -1264,7 +1274,7 @@ gdk_surface_schedule_update (GdkSurface *surface)
if (surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface))
{
surface->pending_schedule_update = TRUE;
surface->pending_phases |= GDK_FRAME_CLOCK_PHASE_PAINT;
return;
}
@ -1317,6 +1327,50 @@ gdk_surface_process_updates_internal (GdkSurface *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
gdk_surface_paint_on_clock (GdkFrameClock *clock,
void *data)
@ -1338,6 +1392,7 @@ gdk_surface_paint_on_clock (GdkFrameClock *clock,
* do the update later when idle instead. */
!surface->in_update)
{
surface->pending_phases &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
gdk_surface_process_updates_internal (surface);
gdk_surface_remove_update_surface (surface);
}
@ -1515,37 +1570,15 @@ gdk_surface_thaw_updates (GdkSurface *surface)
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)
{
surface->pending_schedule_update = FALSE;
gdk_surface_schedule_update (surface);
}
_gdk_frame_clock_inhibit_freeze (frame_clock);
if (surface->pending_phases)
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:
* @geometry: a #GdkGeometry structure
@ -1669,8 +1702,7 @@ gdk_surface_hide (GdkSurface *surface)
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
if (GDK_SURFACE_IS_MAPPED (surface))
gdk_synthesize_surface_state (surface, 0, GDK_TOPLEVEL_STATE_WITHDRAWN);
gdk_surface_queue_set_is_mapped (surface, FALSE);
if (was_mapped)
{
@ -2411,6 +2443,10 @@ gdk_surface_set_frame_clock (GdkSurface *surface,
"resume-events",
G_CALLBACK (gdk_surface_resume_events),
surface);
g_signal_connect (G_OBJECT (clock),
"layout",
G_CALLBACK (gdk_surface_layout_on_clock),
surface);
g_signal_connect (G_OBJECT (clock),
"paint",
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_CALLBACK (gdk_surface_resume_events),
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_CALLBACK (gdk_surface_paint_on_clock),
surface);
@ -2570,58 +2609,10 @@ gdk_surface_set_opaque_region (GdkSurface *surface,
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
gdk_surface_set_state (GdkSurface *surface,
GdkToplevelState new_state)
{
gboolean was_mapped, mapped;
gboolean was_sticky, sticky;
g_return_if_fail (GDK_IS_SURFACE (surface));
@ -2633,20 +2624,15 @@ gdk_surface_set_state (GdkSurface *surface,
* inconsistent state to the user.
*/
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
was_sticky = GDK_SURFACE_IS_STICKY (surface);
surface->state = new_state;
mapped = GDK_SURFACE_IS_MAPPED (surface);
sticky = GDK_SURFACE_IS_STICKY (surface);
if (GDK_IS_TOPLEVEL (surface))
g_object_notify (G_OBJECT (surface), "state");
if (was_mapped != mapped)
g_object_notify_by_pspec (G_OBJECT (surface), properties[PROP_MAPPED]);
if (was_sticky != sticky)
g_object_notify (G_OBJECT (surface), "sticky");
}
@ -2659,6 +2645,94 @@ gdk_synthesize_surface_state (GdkSurface *surface,
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
check_autohide (GdkEvent *event)
{
@ -2770,14 +2844,6 @@ add_event_mark (GdkEvent *event,
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_LEAVE_NOTIFY:
case GDK_TOUCHPAD_SWIPE:
@ -2815,30 +2881,18 @@ add_event_mark (GdkEvent *event,
gboolean
gdk_surface_handle_event (GdkEvent *event)
{
GdkSurface *surface = gdk_event_get_surface (event);
gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
gboolean handled = FALSE;
if (check_autohide (event))
return TRUE;
if (gdk_event_get_event_type (event) == GDK_CONFIGURE)
{
int width, height;
gdk_configure_event_get_size (event, &width, &height);
g_signal_emit (gdk_event_get_surface (event), signals[SIZE_CHANGED], 0,
width, height);
handled = TRUE;
}
else
{
GdkSurface *surface = gdk_event_get_surface (event);
if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY)
surface->request_motion = FALSE;
if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY)
surface->request_motion = FALSE;
g_signal_emit (surface, signals[EVENT], 0, event, &handled);
}
g_signal_emit (surface, signals[EVENT], 0, event, &handled);
if (GDK_PROFILER_IS_RUNNING)
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
void gdk_surface_queue_render (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gdk_surface_request_layout (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
GdkFrameClock* gdk_surface_get_frame_clock (GdkSurface *surface);
@ -125,13 +128,6 @@ GDK_AVAILABLE_IN_ALL
void gdk_surface_set_opaque_region (GdkSurface *surface,
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
GdkCairoContext *gdk_surface_create_cairo_context(GdkSurface *surface);
GDK_AVAILABLE_IN_ALL

View File

@ -44,6 +44,10 @@ struct _GdkSurface
GdkSurface *parent; /* for popups */
GList *children; /* popups */
guint set_is_mapped_source_id;
gboolean pending_is_mapped;
gboolean is_mapped;
gpointer widget;
int x;
@ -53,13 +57,14 @@ struct _GdkSurface
cairo_region_t *update_area;
guint update_freeze_count;
gboolean pending_schedule_update;
GdkFrameClockPhase pending_phases;
/* 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
more than we have to, but it represents the "true" damage. */
cairo_region_t *active_update_area;
GdkToplevelState old_state;
GdkToplevelState pending_set_flags;
GdkToplevelState pending_unset_flags;
GdkToplevelState state;
guint8 resize_count;
@ -83,10 +88,6 @@ struct _GdkSurface
guint update_and_descendants_freeze_count;
int width, height;
int shadow_top;
int shadow_left;
int shadow_right;
int shadow_bottom;
GdkCursor *cursor;
GHashTable *device_cursor;
@ -160,25 +161,24 @@ struct _GdkSurfaceClass
void (* set_opaque_region) (GdkSurface *surface,
cairo_region_t *region);
void (* set_shadow_width) (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
GdkGLContext *(*create_gl_context) (GdkSurface *surface,
gboolean attached,
GdkGLContext *share,
GError **error);
void (* request_layout) (GdkSurface *surface);
gboolean (* compute_size) (GdkSurface *surface);
};
#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,
GdkToplevelState new_state);
void gdk_surface_set_is_mapped (GdkSurface *surface,
gboolean is_mapped);
GdkMonitor * gdk_surface_get_layout_monitor (GdkSurface *surface,
GdkPopupLayout *layout,
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,
int width,
int height,
int shadow_left,
int shadow_right,
int shadow_top,
int shadow_bottom,
GdkMonitor *monitor,
GdkRectangle *bounds,
GdkPopupLayout *layout,
@ -326,9 +330,22 @@ void gdk_surface_constrain_size (GdkGeometry *geometry,
int *new_width,
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
void gdk_surface_request_motion (GdkSurface *surface);
G_END_DECLS
#endif /* __GDK_SURFACE_PRIVATE_H__ */

View File

@ -51,11 +51,10 @@ enum
static guint signals[N_SIGNALS] = { 0 };
static gboolean
static void
gdk_toplevel_default_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
return FALSE;
}
static gboolean
@ -124,7 +123,7 @@ gdk_toplevel_default_init (GdkToplevelInterface *iface)
g_param_spec_flags ("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_object_interface_install_property (iface,
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
* #GdkToplevel::compute-size for details.
*
* Presenting may fail.
*
* Returns: %FALSE if @toplevel failed to be presented, otherwise %TRUE.
* Presenting is asynchronous and the specified layout parameters are not
* guaranteed to be respected.
*/
gboolean
void
gdk_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
g_return_val_if_fail (layout != NULL, FALSE);
g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
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:
* @GDK_TOPLEVEL_STATE_WITHDRAWN: the surface is not shown
* @GDK_TOPLEVEL_STATE_MINIMIZED: the surface is minimized
* @GDK_TOPLEVEL_STATE_MAXIMIZED: the surface is maximized
* @GDK_TOPLEVEL_STATE_STICKY: the surface is sticky
@ -98,23 +97,22 @@ typedef enum
*/
typedef enum
{
GDK_TOPLEVEL_STATE_WITHDRAWN = 1 << 0,
GDK_TOPLEVEL_STATE_MINIMIZED = 1 << 1,
GDK_TOPLEVEL_STATE_MAXIMIZED = 1 << 2,
GDK_TOPLEVEL_STATE_STICKY = 1 << 3,
GDK_TOPLEVEL_STATE_FULLSCREEN = 1 << 4,
GDK_TOPLEVEL_STATE_ABOVE = 1 << 5,
GDK_TOPLEVEL_STATE_BELOW = 1 << 6,
GDK_TOPLEVEL_STATE_FOCUSED = 1 << 7,
GDK_TOPLEVEL_STATE_TILED = 1 << 8,
GDK_TOPLEVEL_STATE_TOP_TILED = 1 << 9,
GDK_TOPLEVEL_STATE_TOP_RESIZABLE = 1 << 10,
GDK_TOPLEVEL_STATE_RIGHT_TILED = 1 << 11,
GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE = 1 << 12,
GDK_TOPLEVEL_STATE_BOTTOM_TILED = 1 << 13,
GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE = 1 << 14,
GDK_TOPLEVEL_STATE_LEFT_TILED = 1 << 15,
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 16
GDK_TOPLEVEL_STATE_MINIMIZED = 1 << 0,
GDK_TOPLEVEL_STATE_MAXIMIZED = 1 << 1,
GDK_TOPLEVEL_STATE_STICKY = 1 << 2,
GDK_TOPLEVEL_STATE_FULLSCREEN = 1 << 3,
GDK_TOPLEVEL_STATE_ABOVE = 1 << 4,
GDK_TOPLEVEL_STATE_BELOW = 1 << 5,
GDK_TOPLEVEL_STATE_FOCUSED = 1 << 6,
GDK_TOPLEVEL_STATE_TILED = 1 << 7,
GDK_TOPLEVEL_STATE_TOP_TILED = 1 << 8,
GDK_TOPLEVEL_STATE_TOP_RESIZABLE = 1 << 9,
GDK_TOPLEVEL_STATE_RIGHT_TILED = 1 << 10,
GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE = 1 << 11,
GDK_TOPLEVEL_STATE_BOTTOM_TILED = 1 << 12,
GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE = 1 << 13,
GDK_TOPLEVEL_STATE_LEFT_TILED = 1 << 14,
GDK_TOPLEVEL_STATE_LEFT_RESIZABLE = 1 << 15
} GdkToplevelState;
@ -129,7 +127,7 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_INTERFACE (GdkToplevel, gdk_toplevel, GDK, TOPLEVEL, GObject)
GDK_AVAILABLE_IN_ALL
gboolean gdk_toplevel_present (GdkToplevel *toplevel,
void gdk_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout);
GDK_AVAILABLE_IN_ALL

View File

@ -13,7 +13,7 @@ struct _GdkToplevelInterface
{
GTypeInterface g_iface;
gboolean (* present) (GdkToplevel *toplevel,
void (* present) (GdkToplevel *toplevel,
GdkToplevelLayout *layout);
gboolean (* minimize) (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;
}
/**
* 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
gdk_toplevel_size_validate (GdkToplevelSize *size)
{
int geometry_width, geometry_height;
if (size->min_width > size->bounds_width ||
size->min_height > size->bounds_height)
g_warning ("GdkToplevelSize: min_size (%d, %d) exceeds bounds (%d, %d)",
size->min_width, size->min_height,
size->bounds_width, size->bounds_height);
if (size->width > size->bounds_width ||
size->height > size->bounds_height)
g_warning ("GdkToplevelSize: size (%d, %d) exceeds bounds (%d, %d)",
geometry_width = size->width;
geometry_height = size->height;
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->bounds_width, size->bounds_height);

View File

@ -54,6 +54,13 @@ void gdk_toplevel_size_set_min_size (GdkToplevelSize *
int min_width,
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
#endif /* __GDK_TOPLEVEL_SIZE_H__ */

View File

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

View File

@ -256,13 +256,7 @@
_gdk_surface_update_size (surface);
/* Synthesize a configure event */
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_surface_request_layout (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),
width,
height,
self->parent_instance.shadow_left,
self->parent_instance.shadow_right,
self->parent_instance.shadow_top,
self->parent_instance.shadow_bottom,
monitor,
&bounds,
self->layout,

View File

@ -125,6 +125,11 @@ void _gdk_macos_surface_set_opacity (GdkMacosSurface
void _gdk_macos_surface_get_root_coords (GdkMacosSurface *self,
int *x,
int *y);
void _gdk_macos_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
int top,
int bottom);
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)
g_signal_emit_by_name (self, "popup-layout-changed");
gdk_surface_request_layout (GDK_SURFACE (self));
}
static void
@ -139,7 +139,7 @@ gdk_macos_surface_get_scale_factor (GdkSurface *surface)
return [self->window backingScaleFactor];
}
static void
void
gdk_macos_surface_set_shadow_width (GdkSurface *surface,
int left,
int right,
@ -491,7 +491,6 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
surface_class->hide = gdk_macos_surface_hide;
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_shadow_width = gdk_macos_surface_set_shadow_width;
properties [PROP_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));
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));

View File

@ -155,6 +155,15 @@ _gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
if (style_mask != [nswindow styleMask])
[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_surface_constrain_size (&geometry, mask, width, height, &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)
(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);
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_notify_committed (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,
cairo_surface_t *cairo_surface,
const cairo_region_t *damage);

View File

@ -122,11 +122,11 @@ struct _GdkWaylandSurface
gint64 pending_frame_counter;
guint32 scale;
int margin_left;
int margin_right;
int margin_top;
int margin_bottom;
gboolean margin_dirty;
int shadow_left;
int shadow_right;
int shadow_top;
int shadow_bottom;
gboolean shadow_dirty;
struct wl_output *initial_fullscreen_output;
@ -162,6 +162,7 @@ struct _GdkWaylandSurface
int width;
int height;
GdkToplevelState state;
gboolean is_resizing;
} toplevel;
struct {
@ -179,6 +180,25 @@ struct _GdkWaylandSurface
gboolean is_dirty;
} 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;
int state_freeze_count;
@ -264,12 +284,17 @@ static void gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int height,
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 maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl);
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_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 void configure_toplevel_geometry (GdkSurface *surface);
static void
gdk_wayland_surface_init (GdkWaylandSurface *impl)
{
@ -336,8 +363,11 @@ _gdk_wayland_surface_save_size (GdkSurface *surface)
GDK_TOPLEVEL_STATE_TILED))
return;
impl->saved_width = surface->width - impl->margin_left - impl->margin_right;
impl->saved_height = surface->height - impl->margin_top - impl->margin_bottom;
if (surface->width <= 1 || surface->height <= 1)
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
@ -582,6 +612,59 @@ on_frame_clock_before_paint (GdkFrameClock *clock,
*/
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
@ -603,6 +686,14 @@ gdk_wayland_surface_request_frame (GdkSurface *surface)
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
gdk_wayland_surface_commit (GdkSurface *surface)
{
@ -801,7 +892,7 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
void
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_input_region (surface);
}
@ -910,16 +1001,6 @@ gdk_wayland_surface_resize (GdkSurface *surface,
{
gdk_wayland_surface_update_size (surface, width, height, scale);
_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,
@ -1069,10 +1150,10 @@ gdk_wayland_surface_get_window_geometry (GdkSurface *surface,
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
*geometry = (GdkRectangle) {
.x = impl->margin_left,
.y = impl->margin_top,
.width = surface->width - (impl->margin_left + impl->margin_right),
.height = surface->height - (impl->margin_top + impl->margin_bottom)
.x = impl->shadow_left,
.y = impl->shadow_top,
.width = surface->width - (impl->shadow_left + impl->shadow_right),
.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);
static void
gdk_wayland_surface_sync_margin (GdkSurface *surface)
gdk_wayland_surface_sync_shadow (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland =
@ -1255,7 +1336,7 @@ gdk_wayland_surface_create_surface (GdkSurface *surface)
}
static void
configure_surface_geometry (GdkSurface *surface)
configure_toplevel_geometry (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
@ -1263,7 +1344,6 @@ configure_surface_geometry (GdkSurface *surface)
GdkRectangle monitor_geometry;
int bounds_width, bounds_height;
GdkToplevelSize size;
int width, height;
GdkToplevelLayout *layout;
GdkGeometry geometry;
GdkSurfaceHints mask;
@ -1276,10 +1356,8 @@ configure_surface_geometry (GdkSurface *surface)
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size);
width = size.width;
height = size.height;
g_warn_if_fail (width > 0);
g_warn_if_fail (height > 0);
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
layout = impl->toplevel.layout;
if (gdk_toplevel_layout_get_resizable (layout))
@ -1290,13 +1368,71 @@ configure_surface_geometry (GdkSurface *surface)
}
else
{
geometry.max_width = geometry.min_width = width;
geometry.max_height = geometry.min_height = height;
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_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
@ -1307,16 +1443,21 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkToplevelState new_state;
int width, height;
gboolean is_resizing;
gboolean fixed_size;
gboolean saved_size;
new_state = impl->pending.toplevel.state;
impl->pending.toplevel.state = 0;
is_resizing = impl->pending.toplevel.is_resizing;
impl->pending.toplevel.is_resizing = FALSE;
fixed_size =
new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
GDK_TOPLEVEL_STATE_FULLSCREEN |
GDK_TOPLEVEL_STATE_TILED);
GDK_TOPLEVEL_STATE_TILED) ||
is_resizing;
width = impl->pending.toplevel.width;
height = impl->pending.toplevel.height;
@ -1338,34 +1479,37 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface)
if (width > 0 && height > 0)
{
GdkSurfaceHints geometry_mask = impl->geometry_mask;
if (!saved_size)
{
/* Do not reapply constrains if we are restoring original size */
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);
impl->next_layout.toplevel.should_constrain = TRUE;
/* Save size for next time we get 0x0 */
_gdk_wayland_surface_save_size (surface);
}
else if (is_resizing)
{
impl->next_layout.toplevel.should_constrain = TRUE;
}
else
{
width += impl->margin_left + impl->margin_right;
height += impl->margin_top + impl->margin_bottom;
impl->next_layout.toplevel.should_constrain = FALSE;
}
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
{
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,
g_message ("configure, surface %p %dx%d,%s%s%s%s",
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_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)
{
@ -1395,6 +1539,7 @@ static void
gdk_wayland_surface_configure_popup (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (surface->parent);
int x, y, width, height;
if (impl->display_server.xdg_popup)
@ -1434,18 +1579,30 @@ gdk_wayland_surface_configure_popup (GdkSurface *surface)
width = impl->pending.popup.width;
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,
x, y,
width, height,
impl->popup.layout);
if (!impl->pending.popup.has_repositioned_token &&
!impl->pending.is_initial_configure)
g_signal_emit_by_name (surface, "popup-layout-changed");
impl->next_layout.popup.x = x;
impl->next_layout.popup.y = y;
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
@ -1458,6 +1615,7 @@ gdk_wayland_surface_configure (GdkSurface *surface)
gdk_surface_thaw_updates (surface);
impl->initial_configure_received = TRUE;
impl->pending.is_initial_configure = TRUE;
maybe_notify_mapped (surface);
}
impl->has_uncommitted_ack_configure = TRUE;
@ -1539,9 +1697,12 @@ xdg_toplevel_configure (void *data,
struct wl_array *states)
{
GdkSurface *surface = GDK_SURFACE (data);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
uint32_t *p;
GdkToplevelState pending_state = 0;
impl->pending.toplevel.is_resizing = FALSE;
wl_array_for_each (p, states)
{
uint32_t state = *p;
@ -1558,6 +1719,7 @@ xdg_toplevel_configure (void *data,
pending_state |= GDK_TOPLEVEL_STATE_FOCUSED;
break;
case XDG_TOPLEVEL_STATE_RESIZING:
impl->pending.toplevel.is_resizing = TRUE;
break;
default:
/* Unknown state */
@ -1628,9 +1790,12 @@ zxdg_toplevel_v6_configure (void *data,
struct wl_array *states)
{
GdkSurface *surface = GDK_SURFACE (data);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
uint32_t *p;
GdkToplevelState pending_state = 0;
impl->pending.toplevel.is_resizing = FALSE;
wl_array_for_each (p, states)
{
uint32_t state = *p;
@ -1647,6 +1812,7 @@ zxdg_toplevel_v6_configure (void *data,
pending_state |= GDK_TOPLEVEL_STATE_FOCUSED;
break;
case ZXDG_TOPLEVEL_V6_STATE_RESIZING:
impl->pending.toplevel.is_resizing = TRUE;
break;
default:
/* Unknown state */
@ -1764,20 +1930,20 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
switch (display_wayland->shell_variant)
{
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);
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);
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,
impl->initial_fullscreen_output);
break;
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);
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);
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,
impl->initial_fullscreen_output);
break;
@ -2098,9 +2264,9 @@ calculate_popup_rect (GdkSurface *surface,
int x = 0, y = 0;
width = (impl->popup.unconstrained_width -
(impl->margin_left + impl->margin_right));
(impl->shadow_left + impl->shadow_right));
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);
gdk_popup_layout_get_offset (layout, &dx, &dy);
@ -2201,26 +2367,12 @@ update_popup_layout_state (GdkSurface *surface,
int height,
GdkPopupLayout *layout)
{
int surface_x, surface_y;
int surface_width, surface_height;
GdkRectangle best_rect;
GdkRectangle flipped_rect;
GdkGravity rect_anchor;
GdkGravity surface_anchor;
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);
surface_anchor = gdk_popup_layout_get_surface_anchor (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);
GdkSurface *parent = surface->parent;
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent);
GdkWaylandDisplay *display =
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkRectangle geometry;
@ -2314,15 +2467,15 @@ create_dynamic_positioner (GdkSurface *surface,
GdkAnchorHints anchor_hints;
geometry = (GdkRectangle) {
.x = impl->margin_left,
.y = impl->margin_top,
.width = width - (impl->margin_left + impl->margin_right),
.height = height - (impl->margin_top + impl->margin_bottom),
.x = impl->shadow_left,
.y = impl->shadow_top,
.width = width - (impl->shadow_left + impl->shadow_right),
.height = height - (impl->shadow_top + impl->shadow_bottom),
};
anchor_rect = gdk_popup_layout_get_anchor_rect (layout);
real_anchor_rect_x = anchor_rect->x - parent->shadow_left;
real_anchor_rect_y = anchor_rect->y - parent->shadow_top;
real_anchor_rect_x = anchor_rect->x - parent_impl->shadow_left;
real_anchor_rect_y = anchor_rect->y - parent_impl->shadow_top;
anchor_rect_width = MAX (anchor_rect->width, 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_SET_PARENT_CONFIGURE_SINCE_VERSION)
{
GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent);
int parent_width;
int parent_height;
parent_width = parent->width - (parent_impl->margin_left +
parent_impl->margin_right);
parent_height = parent->height - (parent_impl->margin_top +
parent_impl->margin_bottom);
parent_width = parent->width - (parent_impl->shadow_left +
parent_impl->shadow_right);
parent_height = parent->height - (parent_impl->shadow_top +
parent_impl->shadow_bottom);
xdg_positioner_set_parent_size (positioner,
parent_width,
@ -2807,6 +2959,12 @@ gdk_wayland_surface_hide_surface (GdkSurface *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);
impl->mapped = FALSE;
}
@ -2982,8 +3140,6 @@ gdk_wayland_surface_map_popup (GdkSurface *surface,
impl->popup.unconstrained_width = width;
impl->popup.unconstrained_height = height;
impl->mapped = TRUE;
gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0);
}
static void
@ -3410,9 +3566,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl,
if (geom_mask & GDK_HINT_MIN_SIZE)
{
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 -
(impl->margin_top + impl->margin_bottom)));
(impl->shadow_top + impl->shadow_bottom)));
}
else
{
@ -3423,9 +3579,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl,
if (geom_mask & GDK_HINT_MAX_SIZE)
{
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 -
(impl->margin_top + impl->margin_bottom)));
(impl->shadow_top + impl->shadow_bottom)));
}
else
{
@ -3608,7 +3764,7 @@ gdk_wayland_surface_maximize (GdkSurface *surface)
}
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
{
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
{
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;
}
}
@ -3714,7 +3870,7 @@ gdk_wayland_surface_fullscreen (GdkSurface *surface)
}
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
{
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;
}
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
gdk_wayland_surface_show_window_menu (GdkSurface *surface,
GdkEvent *event)
@ -4033,8 +4161,9 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
impl_class->drag_begin = _gdk_wayland_surface_drag_begin;
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_shadow_width = gdk_wayland_surface_set_shadow_width;
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
@ -4736,98 +4865,94 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
gdk_toplevel_install_properties (object_class, 1);
}
static void
show_surface (GdkSurface *surface)
static gboolean
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)
return;
if (!impl->toplevel.layout)
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)
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);
return FALSE;
}
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
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,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland;
struct wl_callback *callback;
gboolean done = FALSE;
int last_configure_serial = impl->last_configure_serial;
gboolean needs_reconfigure = TRUE;
gboolean pending_configure = FALSE;
if (gdk_toplevel_layout_get_maximized (layout))
if (did_maximize_layout_change (toplevel, layout))
{
gdk_wayland_surface_maximize (surface);
needs_reconfigure = FALSE;
}
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);
if (gdk_toplevel_layout_get_maximized (layout))
gdk_wayland_surface_maximize (surface);
else
gdk_wayland_surface_fullscreen (surface);
needs_reconfigure = FALSE;
gdk_wayland_surface_unmaximize (surface);
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);
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));
callback = wl_display_sync (display_wayland->wl_display);
wl_proxy_set_queue ((struct wl_proxy *) callback, impl->event_queue);
wl_callback_add_listener (callback,
&reconfigure_listener,
&done);
while (is_realized_toplevel (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;
if (!pending_configure)
{
impl->next_layout.surface_geometry_dirty = TRUE;
gdk_surface_request_layout (surface);
}
}
static gboolean
@ -4961,8 +5086,14 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
GdkSurface *surface = GDK_SURFACE (drag_surface);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gdk_wayland_surface_resize (surface, width, height, impl->scale);
show_surface (surface);
gdk_wayland_surface_show (surface, FALSE);
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;
}

View File

@ -562,7 +562,6 @@ event_mask_string (GdkEventMask mask)
BIT (VISIBILITY_NOTIFY);
BIT (PROXIMITY_IN);
BIT (PROXIMITY_OUT);
BIT (SUBSTRUCTURE);
BIT (SCROLL);
#undef BIT
@ -1278,35 +1277,6 @@ _gdk_win32_get_window_rect (GdkSurface *window,
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 *
_gdk_win32_hrgn_to_region (HRGN hrgn,
guint scale)
@ -2855,11 +2825,6 @@ gdk_event_translate (MSG *msg,
set_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))
set_bits |= GDK_TOPLEVEL_STATE_MINIMIZED;
else
@ -2870,6 +2835,7 @@ gdk_event_translate (MSG *msg,
else
unset_bits |= GDK_TOPLEVEL_STATE_MAXIMIZED;
gdk_surface_set_is_mapped (window, !!IsWindowVisible (msg->hwnd));
gdk_synthesize_surface_state (window, unset_bits, set_bits);
new_state = window->state;
@ -2890,7 +2856,7 @@ gdk_event_translate (MSG *msg,
{
if (!IsIconic (msg->hwnd) &&
!GDK_SURFACE_DESTROYED (window))
_gdk_win32_emit_configure_event (window);
gdk_surface_request_layout (window);
}
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) \
(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 (MAXIMIZED);
BIT (STICKY);

View File

@ -407,7 +407,6 @@ GdkSurface *gdk_win32_display_get_root_window (GdkDisplay *display);
/* Distributed display manager implementation */
GdkDisplay *_gdk_win32_display_open (const char *display_name);
void _gdk_win32_append_event (GdkEvent *event);
void _gdk_win32_emit_configure_event (GdkSurface *window);
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)));
if (GDK_SURFACE_IS_MAPPED (window))
gdk_synthesize_surface_state (window,
0,
GDK_TOPLEVEL_STATE_WITHDRAWN);
gdk_surface_set_is_mapped (window, FALSE);
_gdk_surface_clear_update_area (window);
@ -1190,7 +1188,7 @@ gdk_win32_surface_move_resize_internal (GdkSurface *window,
out:
surface->inhibit_configure = FALSE;
_gdk_win32_emit_configure_event (window);
gdk_surface_request_layout (window);
}
void
@ -1217,6 +1215,7 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
int height,
GdkPopupLayout *layout)
{
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
GdkMonitor *monitor;
GdkRectangle bounds;
GdkRectangle final_rect;
@ -1229,6 +1228,10 @@ gdk_win32_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface,
width,
height,
impl->margins.left,
impl->margins.right,
impl->margins.top,
impl->margins.bottom,
monitor,
&bounds,
layout,
@ -1257,7 +1260,7 @@ static void
show_popup (GdkSurface *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);
gdk_surface_invalidate_rect (surface, NULL);
}
@ -4013,7 +4016,7 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
rect.bottom != new_rect.bottom))
{
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 &&
(rect.left != new_rect.left ||
@ -4021,7 +4024,7 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
{
context->native_move_resize_pending = FALSE;
_gdk_win32_do_emit_configure_event (window, new_rect);
gdk_surface_request_layout (window);
if (impl->layered)
{
@ -4615,8 +4618,6 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
//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->drag_begin = _gdk_win32_surface_drag_begin;
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);
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);
@ -4992,6 +4993,15 @@ gdk_win32_toplevel_present (GdkToplevel *toplevel,
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;
}

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
* enum values match by shifting to the first tiled state.
*/
toplevel->edge_constraints = constraints[0] << 9;
toplevel->edge_constraints = constraints[0] << 8;
XFree (constraints);
}
@ -620,7 +620,6 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
{
Window xwindow;
GdkSurface *surface;
gboolean is_substructure;
GdkX11Surface *surface_impl = NULL;
GdkX11Screen *x11_screen = NULL;
GdkToplevelX11 *toplevel = NULL;
@ -629,18 +628,9 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
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);
is_substructure = xwindow != xevent->xany.window;
if (xwindow != xevent->xany.window)
return NULL;
surface = gdk_x11_surface_lookup_for_display (display, xwindow);
if (surface)
@ -664,7 +654,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
goto done;
}
if (xevent->type == DestroyNotify && !is_substructure)
if (xevent->type == DestroyNotify)
{
x11_screen = GDK_X11_DISPLAY (display)->screen;
@ -793,14 +783,11 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
g_message ("destroy notify:\twindow: %ld",
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)
gdk_surface_destroy_notify (surface);
}
if (surface && GDK_SURFACE_XID (surface) != x11_screen->xroot_window)
gdk_surface_destroy_notify (surface);
break;
@ -809,7 +796,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
g_message ("unmap notify:\t\twindow: %ld",
xevent->xmap.window));
if (surface && !is_substructure)
if (surface)
{
/* If the WM supports the _NET_WM_STATE_HIDDEN hint, we do not want to
* 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",
xevent->xmap.window));
if (surface && !is_substructure)
if (surface)
{
/* Unset minimized if it was set */
if (surface->state & GDK_TOPLEVEL_STATE_MINIMIZED)
@ -902,7 +889,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
}
#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_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)
{
int x, y;
int c_w = (xevent->xconfigure.width + surface_impl->surface_scale - 1) / surface_impl->surface_scale;
int c_h = (xevent->xconfigure.height + surface_impl->surface_scale - 1) / surface_impl->surface_scale;
int configured_width;
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 &&
!xevent->xconfigure.override_redirect &&
@ -946,47 +939,45 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
x = xevent->xconfigure.x / 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_y = y;
new_abs_x = x;
new_abs_y = y;
surface_impl->abs_x = new_abs_x;
surface_impl->abs_y = new_abs_y;
surface_impl->abs_x = new_abs_x;
surface_impl->abs_y = new_abs_y;
if (surface->parent)
{
GdkX11Surface *parent_impl =
GDK_X11_SURFACE (surface->parent);
if (surface->parent)
{
GdkX11Surface *parent_impl =
GDK_X11_SURFACE (surface->parent);
surface->x = new_abs_x - parent_impl->abs_x;
surface->y = new_abs_y - parent_impl->abs_y;
}
surface->x = new_abs_x - parent_impl->abs_x;
surface->y = new_abs_y - parent_impl->abs_y;
}
if (surface_impl->unscaled_width != xevent->xconfigure.width ||
surface_impl->unscaled_height != xevent->xconfigure.height)
{
surface_impl->unscaled_width = xevent->xconfigure.width;
surface_impl->unscaled_height = xevent->xconfigure.height;
gdk_configure_event_get_size (event, &surface->width, &surface->height);
if (surface_impl->unscaled_width != xevent->xconfigure.width ||
surface_impl->unscaled_height != xevent->xconfigure.height)
{
surface_impl->unscaled_width = xevent->xconfigure.width;
surface_impl->unscaled_height = xevent->xconfigure.height;
_gdk_surface_update_size (surface);
_gdk_x11_surface_update_size (surface_impl);
}
surface_impl->next_layout.configured_width = configured_width;
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)
{
surface->resize_count -= 1;
if (surface->resize_count >= 1)
{
surface->resize_count -= 1;
if (surface->resize_count == 0)
_gdk_x11_moveresize_configure_done (display, surface);
}
if (surface->resize_count == 0)
_gdk_x11_moveresize_configure_done (display, surface);
}
gdk_x11_surface_update_popups (surface);
gdk_x11_surface_enter_leave_monitors (surface);
}
gdk_x11_surface_update_popups (surface);
gdk_x11_surface_enter_leave_monitors (surface);
}
break;

View File

@ -2036,7 +2036,7 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
if (gdk_x11_surface_get_group (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);
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);
if ((surface->state & GDK_TOPLEVEL_STATE_WITHDRAWN) == 0)
if (GDK_SURFACE_IS_MAPPED (surface))
return;
/* 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 */
};
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);
/* Forward declarations */
@ -111,6 +119,14 @@ static void gdk_x11_toplevel_state_callback (GdkSurface *surface);
static gboolean gdk_x11_toplevel_event_callback (GdkSurface *surface,
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
* time is concerned. Accounts for wraparound.
*/
@ -192,6 +208,206 @@ gdk_x11_surface_get_unscaled_size (GdkSurface *surface,
*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
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);
}
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
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface)
@ -859,6 +1088,8 @@ connect_frame_clock (GdkSurface *surface)
g_signal_connect (frame_clock, "before-paint",
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_CALLBACK (on_frame_clock_after_paint), surface);
@ -878,6 +1109,8 @@ disconnect_frame_clock (GdkSurface *surface)
g_signal_handlers_disconnect_by_func (frame_clock,
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,
on_frame_clock_after_paint, surface);
@ -1168,7 +1401,7 @@ update_wm_hints (GdkSurface *surface,
if (!force &&
!toplevel->is_leader &&
surface->state & GDK_TOPLEVEL_STATE_WITHDRAWN)
!GDK_SURFACE_IS_MAPPED (surface))
return;
wm_hints.flags = StateHint | InputHint;
@ -1375,9 +1608,7 @@ gdk_x11_surface_withdraw (GdkSurface *surface)
if (!surface->destroyed)
{
if (GDK_SURFACE_IS_MAPPED (surface))
gdk_synthesize_surface_state (surface,
0,
GDK_TOPLEVEL_STATE_WITHDRAWN);
gdk_surface_set_is_mapped (surface, FALSE);
g_assert (!GDK_SURFACE_IS_MAPPED (surface));
XWithdrawWindow (GDK_SURFACE_XDISPLAY (surface),
@ -1388,6 +1619,8 @@ gdk_x11_surface_withdraw (GdkSurface *surface)
static void
gdk_x11_surface_hide (GdkSurface *surface)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
/* We'll get the unmap notify eventually, and handle it then,
* but checking here makes things more consistent if we are
* just doing stuff ourself.
@ -1395,6 +1628,9 @@ gdk_x11_surface_hide (GdkSurface *surface)
_gdk_x11_surface_grab_check_unmap (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);
}
@ -1424,6 +1660,9 @@ x11_surface_move (GdkSurface *surface,
surface->x = x;
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_height = height * impl->surface_scale;
surface->width = width;
surface->height = height;
_gdk_surface_update_size (surface);
_gdk_x11_surface_update_size (GDK_X11_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);
}
else
{
if (width * impl->surface_scale != impl->unscaled_width || height * impl->surface_scale != impl->unscaled_height)
surface->resize_count += 1;
if (width * impl->surface_scale != impl->unscaled_width ||
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_height = height * impl->surface_scale;
surface->width = width;
surface->height = height;
_gdk_x11_surface_update_size (GDK_X11_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);
if (surface->parent)
{
@ -1509,8 +1753,13 @@ x11_surface_move_resize (GdkSurface *surface,
}
else
{
if (width * impl->surface_scale != impl->unscaled_width || height * impl->surface_scale != impl->unscaled_height)
surface->resize_count += 1;
if (width * impl->surface_scale != impl->unscaled_width ||
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,
GdkPopupLayout *layout)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkMonitor *monitor;
GdkRectangle bounds;
GdkRectangle final_rect;
@ -1567,6 +1817,10 @@ gdk_x11_surface_layout_popup (GdkSurface *surface,
gdk_surface_layout_popup_helper (surface,
width,
height,
impl->shadow_left,
impl->shadow_right,
impl->shadow_top,
impl->shadow_bottom,
monitor,
&bounds,
layout,
@ -1596,7 +1850,7 @@ static void
show_popup (GdkSurface *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_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
_gdk_x11_surface_set_surface_scale (GdkSurface *surface,
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:
* @surface: (type GdkX11Surface): a #GdkSurface
@ -4095,6 +4320,9 @@ _gdk_x11_moveresize_configure_done (GdkDisplay *display,
XEvent *tmp_event;
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)
return FALSE;
@ -4565,9 +4793,10 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
impl_class->drag_begin = _gdk_x11_surface_drag_begin;
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_shadow_width = gdk_x11_surface_set_shadow_width;
impl_class->create_gl_context = gdk_x11_surface_create_gl_context;
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
@ -4696,14 +4925,6 @@ gdk_x11_popup_iface_init (GdkPopupInterface *iface)
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);
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);
}
static gboolean
static void
gdk_x11_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
{
GdkSurface *surface = GDK_SURFACE (toplevel);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkMonitor *monitor;
GdkToplevelSize size;
int bounds_width, bounds_height;
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
int width, height;
GdkGeometry geometry;
GdkSurfaceHints mask;
gboolean was_mapped;
if (surface->destroyed)
return;
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
gdk_x11_surface_unminimize (surface);
monitor = gdk_display_get_monitor_at_surface (display, surface);
if (monitor)
{
GdkRectangle workarea;
g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
impl->toplevel_layout = gdk_toplevel_layout_copy (layout);
gdk_x11_monitor_get_workarea (monitor, &workarea);
bounds_width = workarea.width;
bounds_height = workarea.height;
}
else
{
bounds_width = G_MAXINT;
bounds_height = G_MAXINT;
}
gdk_toplevel_size_init (&size, bounds_width, bounds_height);
gdk_toplevel_notify_compute_size (toplevel, &size);
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
width = size.width;
height = size.height;
if (gdk_toplevel_layout_get_resizable (layout))
{
geometry.min_width = 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 (compute_toplevel_size (surface, DONT_UPDATE_GEOMETRY, &width, &height))
gdk_x11_surface_toplevel_resize (surface, width, height);
if (gdk_toplevel_layout_get_maximized (layout))
gdk_x11_surface_maximize (surface);
@ -4921,20 +5110,16 @@ gdk_x11_toplevel_present (GdkToplevel *toplevel,
else
gdk_x11_surface_unfullscreen (surface);
if (surface->destroyed)
return TRUE;
was_mapped = GDK_SURFACE_IS_MAPPED (surface);
impl->next_layout.surface_geometry_dirty = TRUE;
gdk_surface_request_layout (surface);
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);
if (!was_mapped)
gdk_surface_invalidate_rect (surface, NULL);
return TRUE;
}
static gboolean
@ -5100,7 +5285,7 @@ gdk_x11_drag_surface_present (GdkDragSurface *drag_surface,
GdkSurface *surface = GDK_SURFACE (drag_surface);
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_surface_invalidate_rect (surface, NULL);

View File

@ -59,6 +59,11 @@ struct _GdkX11Surface
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
* corner-case where the window manager assigns us a size that isn't
* a multiple of surface_scale - for example for a maximized window
@ -67,6 +72,20 @@ struct _GdkX11Surface
int unscaled_width;
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;
int abs_x;

View File

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

View File

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

View File

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

View File

@ -147,22 +147,22 @@ gtk_drag_icon_move_resize (GtkDragIcon *icon)
}
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 (native);
GtkWidget *widget = GTK_WIDGET (icon);
if (!_gtk_widget_get_alloc_needed (widget))
gtk_widget_ensure_allocate (widget);
else if (gtk_widget_get_visible (widget))
{
gtk_drag_icon_move_resize (icon);
if (icon->surface)
gtk_widget_allocate (widget,
gdk_surface_get_width (icon->surface),
gdk_surface_get_height (icon->surface),
-1, NULL);
}
gtk_drag_icon_move_resize (icon);
}
static void
gtk_drag_icon_native_layout (GtkNative *native,
int width,
int height)
{
gtk_widget_allocate (GTK_WIDGET (native), width, height, -1, NULL);
}
static void
@ -171,7 +171,7 @@ gtk_drag_icon_native_init (GtkNativeInterface *iface)
iface->get_surface = gtk_drag_icon_native_get_surface;
iface->get_renderer = gtk_drag_icon_native_get_renderer;
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
@ -197,6 +197,8 @@ gtk_drag_icon_realize (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_drag_icon_parent_class)->realize (widget);
icon->renderer = gsk_renderer_new_for_surface (icon->surface);
gtk_native_realize (GTK_NATIVE (icon));
}
static void
@ -204,6 +206,8 @@ gtk_drag_icon_unrealize (GtkWidget *widget)
{
GtkDragIcon *icon = GTK_DRAG_ICON (widget);
gtk_native_unrealize (GTK_NATIVE (icon));
GTK_WIDGET_CLASS (gtk_drag_icon_parent_class)->unrealize (widget);
gsk_renderer_unrealize (icon->renderer);
@ -279,7 +283,7 @@ gtk_drag_icon_show (GtkWidget *widget)
_gtk_widget_set_visible_flag (widget, TRUE);
gtk_css_node_validate (gtk_widget_get_css_node (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);
}
@ -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);
gtk_widget_show (self);
if (GTK_DRAG_ICON (self)->child != NULL)
gtk_widget_show (self);
}
return self;
@ -472,7 +477,10 @@ gtk_drag_icon_set_child (GtkDragIcon *self,
self->child = 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]);
}

View File

@ -383,7 +383,7 @@ gtk_drop_down_size_allocate (GtkWidget *widget,
gtk_widget_set_size_request (self->popup, width, -1);
gtk_widget_queue_resize (self->popup);
gtk_native_check_resize (GTK_NATIVE (self->popup));
gtk_popover_present (GTK_POPOVER (self->popup));
}
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);
if (child->variations)
gtk_native_check_resize (GTK_NATIVE (child->variations));
gtk_popover_present (GTK_POPOVER (child->variations));
}
static gboolean

View File

@ -181,7 +181,6 @@ struct _GtkEntryPrivate
GtkWidget *text;
GtkWidget *progress_widget;
GtkWidget *emoji_chooser;
guint show_emoji_icon : 1;
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->emoji_chooser, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_entry_parent_class)->dispose (object);
}
@ -1803,9 +1800,6 @@ gtk_entry_size_allocate (GtkWidget *widget,
if (completion)
_gtk_entry_completion_resize_popup (completion);
}
if (priv->emoji_chooser)
gtk_native_check_resize (GTK_NATIVE (priv->emoji_chooser));
}
static void

View File

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

View File

@ -727,23 +727,7 @@ gtk_expander_resize_toplevel (GtkExpander *expander)
if (GTK_IS_WINDOW (toplevel) &&
gtk_widget_get_realized (toplevel))
{
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);
}
gtk_widget_queue_resize (GTK_WIDGET (expander));
}
}

View File

@ -628,7 +628,7 @@ save_dialog_geometry (GtkFileChooserDialog *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);
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);
GTK_WIDGET_CLASS (gtk_file_chooser_widget_parent_class)->size_allocate (widget, width, height, baseline);
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)
gtk_native_check_resize (GTK_NATIVE (impl->rename_file_popover));
gtk_popover_present (GTK_POPOVER (impl->rename_file_popover));
}
static void

View File

@ -130,8 +130,6 @@ struct _GtkHeaderBar
guint show_title_buttons : 1;
guint track_default_decoration : 1;
GdkToplevelState state;
};
typedef struct _GtkHeaderBarClass GtkHeaderBarClass;
@ -613,7 +611,6 @@ gtk_header_bar_init (GtkHeaderBar *bar)
bar->title_widget = NULL;
bar->decoration_layout = NULL;
bar->show_title_buttons = TRUE;
bar->state = GDK_TOPLEVEL_STATE_WITHDRAWN;
bar->handle = gtk_window_handle_new ();
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)
gtk_native_check_resize (GTK_NATIVE (self->popup_menu));
gtk_popover_present (GTK_POPOVER (self->popup_menu));
}
static void

View File

@ -77,6 +77,9 @@
#include "gtklayoutchild.h"
#include "gtkwidgetprivate.h"
#include "gtknative.h"
#include "gtkpopover.h"
#include "gtktexthandleprivate.h"
#include "gtktooltipwindowprivate.h"
#ifdef G_ENABLE_DEBUG
#define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method) G_STMT_START { \
@ -363,8 +366,15 @@ allocate_native_children (GtkWidget *widget)
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (GTK_IS_NATIVE (child))
gtk_native_check_resize (GTK_NATIVE (child));
if (GTK_IS_POPOVER (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 },
baseline);
if (self->popover)
gtk_native_check_resize (GTK_NATIVE (self->popover));
gtk_popover_present (GTK_POPOVER (self->popover));
}
static gboolean

View File

@ -24,6 +24,15 @@
#include "gdk/gdk-private.h"
#include "gtkprivate.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
@ -55,7 +64,9 @@ gtk_native_default_get_surface_transform (GtkNative *self,
}
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_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);
}
/**
* 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:
* @surface: a #GdkSurface
@ -157,3 +239,19 @@ gtk_native_get_for_surface (GdkSurface *surface)
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
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
GtkNative * gtk_native_get_for_surface (GdkSurface *surface);
GDK_AVAILABLE_IN_ALL
void gtk_native_check_resize (GtkNative *self);
GDK_AVAILABLE_IN_ALL
GdkSurface *gtk_native_get_surface (GtkNative *self);

View File

@ -23,9 +23,13 @@ struct _GtkNativeInterface
double *x,
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
#endif /* __GTK_NATIVE_PRIVATE_H__ */

View File

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

View File

@ -36,6 +36,7 @@
#include "gtkstack.h"
#include "gtktypebuiltins.h"
#include "gtknative.h"
#include "gtkpopover.h"
#else
#include <gtk/gtk.h>
#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);
if (menu)
gtk_native_check_resize (GTK_NATIVE (menu));
gtk_popover_present (GTK_POPOVER (menu));
}
static void

View File

@ -419,11 +419,6 @@ update_popover_layout (GtkPopover *popover,
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));
}
@ -582,10 +577,9 @@ present_popup (GtkPopover *popover)
return FALSE;
}
static void
gtk_popover_native_check_resize (GtkNative *native)
void
gtk_popover_present (GtkPopover *popover)
{
GtkPopover *popover = GTK_POPOVER (native);
GtkWidget *widget = GTK_WIDGET (popover);
if (!_gtk_widget_get_alloc_needed (widget))
@ -594,6 +588,61 @@ gtk_popover_native_check_resize (GtkNative *native)
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
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));
}
static void
surface_size_changed (GtkWidget *widget,
guint width,
guint height)
{
}
static gboolean
surface_render (GdkSurface *surface,
cairo_region_t *region,
@ -761,16 +803,6 @@ surface_event (GdkSurface *surface,
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
gtk_popover_activate_default (GtkPopover *popover)
{
@ -887,14 +919,14 @@ gtk_popover_realize (GtkWidget *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, "size-changed", G_CALLBACK (surface_size_changed), 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, "popup-layout-changed", G_CALLBACK (popup_layout_changed), widget);
GTK_WIDGET_CLASS (gtk_popover_parent_class)->realize (widget);
priv->renderer = gsk_renderer_new_for_surface (priv->surface);
gtk_native_realize (GTK_NATIVE (popover));
}
static void
@ -903,16 +935,16 @@ gtk_popover_unrealize (GtkWidget *widget)
GtkPopover *popover = GTK_POPOVER (widget);
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
gtk_native_unrealize (GTK_NATIVE (popover));
GTK_WIDGET_CLASS (gtk_popover_parent_class)->unrealize (widget);
gsk_renderer_unrealize (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_size_changed, 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, popup_layout_changed, widget);
gdk_surface_set_widget (priv->surface, NULL);
gdk_surface_destroy (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_renderer = gtk_popover_native_get_renderer;
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;

View File

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

View File

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

View File

@ -21,6 +21,7 @@
#include "gtkrootprivate.h"
#include "gtknative.h"
#include "gtknativeprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkwidgetprivate.h"
#include "gdk/gdk-private.h"
@ -43,9 +44,6 @@
* 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_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_focus = gtk_root_default_get_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);
}
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
gtk_root_start_layout (GtkRoot *self)
{
GdkFrameClock *clock;
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);
gtk_native_queue_relayout (GTK_NATIVE (self));
}
void
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
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);
}

View File

@ -1001,5 +1001,5 @@ gtk_scale_button_size_allocate (GtkWidget *widget,
&(GtkAllocation) { 0, 0, width, height },
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");
if (chooser)
gtk_native_check_resize (GTK_NATIVE (chooser));
gtk_popover_present (GTK_POPOVER (chooser));
gtk_text_update_handles (self);
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)
gtk_native_check_resize (GTK_NATIVE (priv->magnifier_popover));
gtk_popover_present (GTK_POPOVER (priv->magnifier_popover));
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)
gtk_native_check_resize (GTK_NATIVE (priv->selection_bubble));
gtk_popover_present (GTK_POPOVER (priv->selection_bubble));
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])
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

View File

@ -162,18 +162,12 @@ gtk_text_handle_present_surface (GtkTextHandle *handle)
MAX (req.height, 1),
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
gtk_text_handle_native_check_resize (GtkNative *native)
void
gtk_text_handle_present (GtkTextHandle *handle)
{
GtkTextHandle *handle = GTK_TEXT_HANDLE (native);
GtkWidget *widget = GTK_WIDGET (native);
GtkWidget *widget = GTK_WIDGET (handle);
if (!_gtk_widget_get_alloc_needed (widget))
gtk_widget_ensure_allocate (widget);
@ -181,13 +175,26 @@ gtk_text_handle_native_check_resize (GtkNative *native)
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
gtk_text_handle_native_interface_init (GtkNativeInterface *iface)
{
iface->get_surface = gtk_text_handle_native_get_surface;
iface->get_renderer = gtk_text_handle_native_get_renderer;
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
@ -240,6 +247,8 @@ gtk_text_handle_realize (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_text_handle_parent_class)->realize (widget);
handle->renderer = gsk_renderer_new_for_surface (handle->surface);
gtk_native_realize (GTK_NATIVE (handle));
}
static void
@ -247,6 +256,8 @@ gtk_text_handle_unrealize (GtkWidget *widget)
{
GtkTextHandle *handle = GTK_TEXT_HANDLE (widget);
gtk_native_unrealize (GTK_NATIVE (handle));
GTK_WIDGET_CLASS (gtk_text_handle_parent_class)->unrealize (widget);
gsk_renderer_unrealize (handle->renderer);

View File

@ -35,6 +35,8 @@ typedef enum
GtkTextHandle * gtk_text_handle_new (GtkWidget *parent);
void gtk_text_handle_present (GtkTextHandle *handle);
void gtk_text_handle_set_role (GtkTextHandle *handle,
GtkTextHandleRole role);
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");
if (chooser)
gtk_native_check_resize (GTK_NATIVE (chooser));
gtk_popover_present (GTK_POPOVER (chooser));
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)
gtk_native_check_resize (GTK_NATIVE (priv->popup_menu));
gtk_popover_present (GTK_POPOVER (priv->popup_menu));
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])
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)
gtk_native_check_resize (GTK_NATIVE (priv->selection_bubble));
gtk_popover_present (GTK_POPOVER (priv->selection_bubble));
}
static void

View File

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

View File

@ -47,7 +47,6 @@ struct _GtkTooltipWindow
GdkSurface *surface;
GskRenderer *renderer;
GdkToplevelState state;
GtkWidget *relative_to;
GdkRectangle rect;
GdkGravity rect_anchor;
@ -139,11 +138,10 @@ gtk_tooltip_window_relayout (GtkTooltipWindow *window)
gdk_popup_layout_unref (layout);
}
static void
gtk_tooltip_window_native_check_resize (GtkNative *native)
void
gtk_tooltip_window_present (GtkTooltipWindow *window)
{
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (native);
GtkWidget *widget = GTK_WIDGET (native);
GtkWidget *widget = GTK_WIDGET (window);
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))
{
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
gtk_tooltip_window_native_init (GtkNativeInterface *iface)
{
iface->get_surface = gtk_tooltip_window_native_get_surface;
iface->get_renderer = gtk_tooltip_window_native_get_renderer;
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
surface_state_changed (GtkWidget *widget)
mapped_changed (GdkSurface *surface,
GParamSpec *pspec,
GtkWidget *widget)
{
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget);
GdkToplevelState new_surface_state;
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);
}
if (!gdk_surface_get_mapped (surface))
gtk_widget_hide (widget);
}
static gboolean
@ -216,13 +214,15 @@ gtk_tooltip_window_realize (GtkWidget *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, "event", G_CALLBACK (surface_event), widget);
GTK_WIDGET_CLASS (gtk_tooltip_window_parent_class)->realize (widget);
window->renderer = gsk_renderer_new_for_surface (window->surface);
gtk_native_realize (GTK_NATIVE (window));
}
static void
@ -230,12 +230,14 @@ gtk_tooltip_window_unrealize (GtkWidget *widget)
{
GtkTooltipWindow *window = GTK_TOOLTIP_WINDOW (widget);
gtk_native_unrealize (GTK_NATIVE (window));
GTK_WIDGET_CLASS (gtk_tooltip_window_parent_class)->unrealize (widget);
gsk_renderer_unrealize (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_event, widget);
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_realize (widget);
gtk_tooltip_window_native_check_resize (GTK_NATIVE (widget));
gtk_tooltip_window_present (GTK_TOOLTIP_WINDOW (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);
void gtk_tooltip_window_present (GtkTooltipWindow *window);
void gtk_tooltip_window_set_label_markup (GtkTooltipWindow *window,
const char *markup);
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)
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 */

View File

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

View File

@ -229,6 +229,8 @@ void gtk_widget_ensure_resize (GtkWidget *widget);
void gtk_widget_ensure_allocate (GtkWidget *widget);
void _gtk_widget_scale_changed (GtkWidget *widget);
GdkSurface * gtk_widget_get_surface (GtkWidget *widget);
void gtk_widget_render (GtkWidget *widget,
GdkSurface *surface,
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,
int *width,
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
GtkWindowGroup *gtk_window_get_group (GtkWindow *window);
@ -251,6 +243,9 @@ GtkWidget *gtk_window_get_titlebar (GtkWindow *window);
GDK_AVAILABLE_IN_ALL
gboolean gtk_window_is_maximized (GtkWindow *window);
GDK_AVAILABLE_IN_ALL
gboolean gtk_window_is_fullscreen (GtkWindow *window);
GDK_AVAILABLE_IN_ALL
void gtk_window_destroy (GtkWindow *window);

View File

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

View File

@ -455,6 +455,15 @@ value_is_default (Element *element,
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
ret = g_param_value_defaults (pspec, &value);
}

View File

@ -123,17 +123,16 @@ on_frame (double progress)
window_height = HEIGHT + jitter;
}
gtk_window_resize (GTK_WINDOW (window),
window_width, window_height);
gtk_window_set_default_size (GTK_WINDOW (window),
window_width, window_height);
gtk_widget_queue_draw (window);
}
static gboolean
tick_callback (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
resize_idle (gpointer user_data)
{
GdkFrameClock *frame_clock = user_data;
gint64 frame_time = gdk_frame_clock_get_frame_time (frame_clock);
double scaled_time;
@ -143,6 +142,16 @@ tick_callback (GtkWidget *widget,
scaled_time = (frame_time - start_frame_time) / (CYCLE_TIME * 1000000);
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;
}

View File

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

View File

@ -4531,8 +4531,6 @@ surface_state_callback (GdkSurface *window,
new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (window));
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) ?
"minimized" : "not minimized", ", ",
(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));
}
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
unset_default_size_callback (GtkWidget *widget,
gpointer data)
@ -4891,13 +4878,6 @@ window_controls (GtkWidget *window)
G_CONNECT_SWAPPED);
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");
g_signal_connect (button,
"clicked",

View File

@ -46,7 +46,7 @@ int main (int argc, char **argv)
gtk_init ();
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 ();
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 *resizable_check;
static void
size_changed_cb (GdkSurface *surface, int width, int height, GtkLabel *label)
static gboolean
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;
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);
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
@ -63,8 +76,8 @@ show_dialog (void)
gtk_dialog_add_action_widget (GTK_DIALOG (dialog), label, GTK_RESPONSE_HELP);
gtk_widget_realize (dialog);
g_signal_connect (gtk_native_get_surface (GTK_NATIVE (dialog)), "size-changed",
G_CALLBACK (size_changed_cb), label);
g_signal_connect (gtk_native_get_surface (GTK_NATIVE (dialog)), "layout",
G_CALLBACK (layout_cb), label);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy),
NULL);

View File

@ -4691,7 +4691,6 @@ specific_append_after_collapse (void)
window = gtk_window_new ();
tree_view = gtk_tree_view_new_with_model (sort);
gtk_window_set_child (GTK_WINDOW (window), tree_view);
gtk_widget_realize (tree_view);
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE);
@ -4811,7 +4810,6 @@ specific_sort_filter_remove_node (void)
window = gtk_window_new ();
tree_view = gtk_tree_view_new_with_model (filter);
gtk_window_set_child (GTK_WINDOW (window), tree_view);
gtk_widget_realize (tree_view);
while (g_main_context_pending (NULL))
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, "is-focus") ||
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;
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));
}
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
test_resize_popup (void)
{
@ -220,7 +157,7 @@ test_resize_popup (void)
/* testcase for the dnd window */
window = gtk_window_new ();
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);
g_assert_cmpint (w, ==, 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/resize", test_resize);
g_test_add_func ("/window/resize-popup", test_resize_popup);
g_test_add_func ("/window/show-hide", test_show_hide);

View File

@ -439,8 +439,6 @@ testdata = [
'window-default-size.ui',
'window-height-for-width.ref.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.

View File

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

View File

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