}
}
--(void)windowDidUnmaximize
+-(void)setFrame:(NSRect)frame display:(BOOL)display
{
- NSWindowStyleMask style_mask = [self styleMask];
-
- gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
+ NSRect contentRect = [self contentRectForFrameRect:frame];
+ GdkSurface *surface = GDK_SURFACE (gdk_surface);
+ gboolean maximized = (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
- /* If we are using CSD, then we transitioned to an opaque
- * window while we were maximized. Now we need to drop that
- * as we are leaving maximized state.
- */
- if ((style_mask & NSWindowStyleMaskTitled) == 0 && [self isOpaque])
+ if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, frame))
{
- GdkSurface *surface = GDK_SURFACE ([self gdkSurface]);
-
- [self setOpaque:NO];
-
- /* Force updating of various styling, regions, etc */
+ gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0);
_gdk_surface_update_size (surface);
}
-}
--(void)windowDidMove:(NSNotification *)aNotification
-{
- GdkSurface *surface = GDK_SURFACE (gdk_surface);
- gboolean maximized = (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
-
- /* In case the window is changed when maximized remove the maximized state */
- if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
- [self windowDidUnmaximize];
-
- _gdk_macos_surface_update_position (gdk_surface);
- _gdk_macos_surface_reposition_children (gdk_surface);
-
- [self checkSendEnterNotify];
-}
-
--(void)windowDidResize:(NSNotification *)aNotification
-{
- NSRect content_rect;
- GdkSurface *surface;
- GdkDisplay *display;
- gboolean maximized;
-
- surface = GDK_SURFACE (gdk_surface);
- display = gdk_surface_get_display (surface);
-
- content_rect = [self contentRectForFrameRect:[self frame]];
- maximized = (surface->state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
-
- /* see same in windowDidMove */
- if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
- [self windowDidUnmaximize];
-
- surface->width = content_rect.size.width;
- surface->height = content_rect.size.height;
-
- /* Certain resize operations (e.g. going fullscreen), also move the
- * origin of the window.
- */
- _gdk_macos_surface_update_position (GDK_MACOS_SURFACE (surface));
-
- [[self contentView] setFrame:NSMakeRect (0, 0, surface->width, surface->height)];
-
- _gdk_surface_update_size (surface);
-
- gdk_surface_request_layout (surface);
-
- _gdk_macos_surface_reposition_children (gdk_surface);
-
- [self checkSendEnterNotify];
+ [super setFrame:frame display:display];
+ [[self contentView] setFrame:NSMakeRect (0, 0, contentRect.size.width, contentRect.size.height)];
}
-(id)initWithContentRect:(NSRect)contentRect
windowFrame.origin.x = new_origin.x;
windowFrame.origin.y = new_origin.y;
- /* And now apply the frame to the window */
- [self setFrameOrigin:NSMakePoint(new_origin.x, new_origin.y)];
+ [self setFrame:NSMakeRect (new_origin.x, new_origin.y,
+ window_gdk.width, window_gdk.height)
+ display:YES];
return YES;
}
+-(void)windowDidMove:(NSNotification *)notification
+{
+ _gdk_macos_surface_configure ([self gdkSurface]);
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+ _gdk_macos_surface_configure ([self gdkSurface]);
+}
+
/* Used by gdkmacosdisplay-translate.c to decide if our sendEvent() handler
* above will see the event or if it will be subjected to standard processing
* by GDK.
-(void)beginManualMove
{
+ gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
NSPoint initialMoveLocation;
GdkPoint point;
GdkMonitor *monitor;
initialMoveLocation = [NSEvent mouseLocation];
+ if (maximized)
+ [self setFrame:NSMakeRect (initialMoveLocation.x - (int)lastUnmaximizedFrame.size.width/2,
+ initialMoveLocation.y,
+ lastUnmaximizedFrame.size.width,
+ lastUnmaximizedFrame.size.height)
+ display:YES];
+
_gdk_macos_display_from_display_coords ([self gdkDisplay],
initialMoveLocation.x,
initialMoveLocation.y,
new_frame.size.height = min_size.height;
}
- /* We could also apply aspect ratio:
- new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
- */
-
- [self setFrame:new_frame display:YES];
-
- /* Let the resizing be handled by GTK. */
- if (g_main_context_pending (NULL))
- g_main_context_iteration (NULL, FALSE);
+ _gdk_macos_surface_user_resize ([self gdkSurface], new_frame);
inTrackManualResize = NO;
-(void)beginManualResize:(GdkSurfaceEdge)edge
{
+ CALayerContentsGravity gravity = kCAGravityBottomLeft;
+
if (inMove || inManualMove || inManualResize)
return;
inManualResize = YES;
resizeEdge = edge;
- if (GDK_IS_MACOS_GL_VIEW ([self contentView]))
+ switch (edge)
{
- CALayerContentsGravity gravity = kCAGravityBottomLeft;
+ default:
+ case GDK_SURFACE_EDGE_NORTH:
+ gravity = kCAGravityTopLeft;
+ break;
- switch (edge)
- {
- default:
- case GDK_SURFACE_EDGE_NORTH:
- gravity = kCAGravityTopLeft;
- break;
-
- case GDK_SURFACE_EDGE_NORTH_WEST:
- gravity = kCAGravityTopRight;
- break;
-
- case GDK_SURFACE_EDGE_SOUTH_WEST:
- case GDK_SURFACE_EDGE_WEST:
- gravity = kCAGravityBottomRight;
- break;
-
- case GDK_SURFACE_EDGE_SOUTH:
- case GDK_SURFACE_EDGE_SOUTH_EAST:
- gravity = kCAGravityBottomLeft;
- break;
-
- case GDK_SURFACE_EDGE_EAST:
- gravity = kCAGravityBottomLeft;
- break;
-
- case GDK_SURFACE_EDGE_NORTH_EAST:
- gravity = kCAGravityTopLeft;
- break;
- }
+ case GDK_SURFACE_EDGE_NORTH_WEST:
+ gravity = kCAGravityTopRight;
+ break;
+
+ case GDK_SURFACE_EDGE_SOUTH_WEST:
+ case GDK_SURFACE_EDGE_WEST:
+ gravity = kCAGravityBottomRight;
+ break;
+
+ case GDK_SURFACE_EDGE_SOUTH:
+ case GDK_SURFACE_EDGE_SOUTH_EAST:
+ gravity = kCAGravityBottomLeft;
+ break;
+
+ case GDK_SURFACE_EDGE_EAST:
+ gravity = kCAGravityBottomLeft;
+ break;
- [[[self contentView] layer] setContentsGravity:gravity];
+ case GDK_SURFACE_EDGE_NORTH_EAST:
+ gravity = kCAGravityTopLeft;
+ break;
}
+ [[[self contentView] layer] setContentsGravity:gravity];
+
initialResizeFrame = [self frame];
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
}
if (state & GDK_TOPLEVEL_STATE_MAXIMIZED)
{
lastMaximizedFrame = newFrame;
- [self windowDidUnmaximize];
}
else
{
-(void)windowDidEndLiveResize:(NSNotification *)aNotification
{
- gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_TOPLEVEL_STATE_MAXIMIZED;
-
inMaximizeTransition = NO;
-
- /* Even if this is CSD, we want to be opaque while maximized
- * to speed up compositing by allowing the display server to
- * avoid costly blends.
- */
- if (maximized)
- [self setOpaque:YES];
}
-(NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
g_assert (GDK_IS_MACOS_SURFACE (surface));
if (GDK_IS_TOPLEVEL (surface))
- _gdk_macos_surface_update_position (surface);
+ _gdk_macos_surface_configure (surface);
}
}
int root_x;
int root_y;
+ struct {
+ int root_x;
+ int root_y;
+ int width;
+ int height;
+ } next_layout;
+
int shadow_top;
int shadow_right;
int shadow_bottom;
int width,
int height);
void _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self);
-void _gdk_macos_surface_update_position (GdkMacosSurface *self);
void _gdk_macos_surface_show (GdkMacosSurface *self);
void _gdk_macos_surface_publish_timings (GdkMacosSurface *self,
gint64 predicted_presentation_time,
int y,
int width,
int height);
+void _gdk_macos_surface_configure (GdkMacosSurface *self);
+void _gdk_macos_surface_user_resize (GdkMacosSurface *self,
+ CGRect new_frame);
gboolean _gdk_macos_surface_is_tracking (GdkMacosSurface *self,
NSTrackingArea *area);
void _gdk_macos_surface_monitor_changed (GdkMacosSurface *self);
G_OBJECT_CLASS (gdk_macos_surface_parent_class)->constructed (object);
- if (self->window != NULL)
- {
- NSRect bounds = [[self->window contentView] bounds];
-
- GDK_SURFACE (self)->width = bounds.size.width;
- GDK_SURFACE (self)->height = bounds.size.height;
- _gdk_macos_surface_update_position (self);
- }
-
if ((frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self))))
{
g_signal_connect_object (frame_clock,
self,
G_CONNECT_SWAPPED);
}
+
+ if (self->window != NULL)
+ _gdk_macos_surface_configure (self);
}
static void
}
void
-_gdk_macos_surface_update_position (GdkMacosSurface *self)
+_gdk_macos_surface_configure (GdkMacosSurface *self)
{
- GdkSurface *surface = GDK_SURFACE (self);
- GdkDisplay *display = gdk_surface_get_display (surface);
- NSRect frame_rect = [self->window frame];
- NSRect content_rect = [self->window contentRectForFrameRect:frame_rect];
+ GdkMacosDisplay *display;
+ GdkSurface *surface = (GdkSurface *)self;
+ NSRect frame_rect;
+ NSRect content_rect;
+
+ g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
+
+ if (GDK_SURFACE_DESTROYED (self))
+ return;
+
+ display = GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display);
+ frame_rect = [self->window frame];
+ content_rect = [self->window contentRectForFrameRect:frame_rect];
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display),
content_rect.origin.x,
surface->x = self->root_x;
surface->y = self->root_y;
}
+
+ if (surface->width != content_rect.size.width ||
+ surface->height != content_rect.size.height)
+ {
+ surface->width = content_rect.size.width;
+ surface->height = content_rect.size.height;
+
+ _gdk_surface_update_size (surface);
+ gdk_surface_request_layout (surface);
+ gdk_surface_invalidate_rect (surface, NULL);
+ }
+
+ _gdk_macos_surface_reposition_children (self);
}
void
{
if (gdk_surface_get_mapped (GDK_SURFACE (self)))
{
- _gdk_macos_surface_update_position (self);
- gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
+ _gdk_macos_surface_configure (self);
gdk_surface_thaw_updates (GDK_SURFACE (self));
}
}
GdkDisplay *display;
NSRect content_rect;
NSRect frame_rect;
- gboolean size_changed;
g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
if (y == -1)
y = self->root_y;
- size_changed = height != surface->height || width != surface->width;
-
- if (GDK_IS_MACOS_SURFACE (surface->parent))
- {
- surface->x = x - GDK_MACOS_SURFACE (surface->parent)->root_x;
- surface->y = y - GDK_MACOS_SURFACE (surface->parent)->root_y;
- }
- else
- {
- surface->x = x;
- surface->y = y;
- }
-
_gdk_macos_display_to_display_coords (GDK_MACOS_DISPLAY (display),
- x, y + height, &x, &y);
+ x, y + height,
+ &x, &y);
content_rect = NSMakeRect (x, y, width, height);
frame_rect = [self->window frameRectForContentRect:content_rect];
[self->window setFrame:frame_rect display:YES];
+}
+
+void
+_gdk_macos_surface_user_resize (GdkMacosSurface *self,
+ CGRect new_frame)
+{
+ GdkMacosDisplay *display;
+ CGRect content_rect;
+ int root_x, root_y;
+
+ g_return_if_fail (GDK_IS_MACOS_SURFACE (self));
+ g_return_if_fail (GDK_IS_TOPLEVEL (self));
+
+ if (GDK_SURFACE_DESTROYED (self))
+ return;
+
+ display = GDK_MACOS_DISPLAY (GDK_SURFACE (self)->display);
+ content_rect = [self->window contentRectForFrameRect:new_frame];
+
+ _gdk_macos_display_from_display_coords (display,
+ new_frame.origin.x,
+ new_frame.origin.y + new_frame.size.height,
+ &root_x, &root_y);
- if (size_changed)
- gdk_surface_invalidate_rect (surface, NULL);
+ self->next_layout.root_x = root_x;
+ self->next_layout.root_y = root_y;
+ self->next_layout.width = content_rect.size.width;
+ self->next_layout.height = content_rect.size.height;
+
+ gdk_surface_request_layout (GDK_SURFACE (self));
}
gboolean
g_object_unref (monitor);
}
- _gdk_surface_update_size (GDK_SURFACE (self));
+ _gdk_macos_surface_configure (self);
+
gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
}
{
GdkMacosSurface parent_instance;
GdkToplevelLayout *layout;
+ int last_computed_width;
+ int last_computed_height;
guint decorated : 1;
};
_gdk_macos_toplevel_surface_compute_size (GdkSurface *surface)
{
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
+ GdkMacosSurface *macos_surface = (GdkMacosSurface *)surface;
GdkToplevelSize size;
GdkDisplay *display;
GdkMonitor *monitor;
int bounds_width, bounds_height;
- int width, height;
GdkGeometry geometry;
GdkSurfaceHints mask;
g_warn_if_fail (size.width > 0);
g_warn_if_fail (size.height > 0);
- width = surface->width;
- height = surface->height;
-
if (self->layout != NULL &&
gdk_toplevel_layout_get_resizable (self->layout))
{
}
if (size.shadow.is_valid)
- _gdk_macos_surface_set_shadow (GDK_MACOS_SURFACE (surface),
+ _gdk_macos_surface_set_shadow (macos_surface,
size.shadow.top,
size.shadow.right,
size.shadow.bottom,
size.shadow.left);
- gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
+ _gdk_macos_surface_set_geometry_hints (macos_surface, &geometry, mask);
- _gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
- _gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
+ 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))
+ return FALSE;
+
+ /* If we delayed a user resize until the beginning of the frame,
+ * apply it now so we can start processing updates for it.
+ */
+ if (macos_surface->next_layout.width > 0 &&
+ macos_surface->next_layout.height > 0)
+ {
+ int root_x = macos_surface->next_layout.root_x;
+ int root_y = macos_surface->next_layout.root_y;
+ int width = macos_surface->next_layout.width;
+ int height = macos_surface->next_layout.height;
+
+ gdk_surface_constrain_size (&geometry, mask,
+ width, height,
+ &width, &height);
+
+ macos_surface->next_layout.width = 0;
+ macos_surface->next_layout.height = 0;
+
+ _gdk_macos_surface_move_resize (macos_surface,
+ root_x, root_y,
+ width, height);
+
+ return FALSE;
+ }
+
+ gdk_surface_constrain_size (&geometry, mask,
+ size.width, size.height,
+ &size.width, &size.height);
+
+ if ((size.width != self->last_computed_width ||
+ size.height != self->last_computed_height) &&
+ (size.width != surface->width ||
+ size.height != surface->height))
+ {
+ self->last_computed_width = size.width;
+ self->last_computed_height = size.height;
+
+ _gdk_macos_surface_resize (macos_surface, size.width, size.height);
+ }
return FALSE;
}