diff --git a/gdk/quartz/GdkQuartzWindow.c b/gdk/quartz/GdkQuartzWindow.c index a974bdaee3..d38fe22a14 100644 --- a/gdk/quartz/GdkQuartzWindow.c +++ b/gdk/quartz/GdkQuartzWindow.c @@ -144,8 +144,9 @@ GdkWindowObject *private = (GdkWindowObject *)window; GdkEvent *event; - private->x = content_rect.origin.x; - private->y = _gdk_quartz_window_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height); + _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x, + content_rect.origin.y + content_rect.size.height, + &private->x, &private->y); /* Synthesize a configure event */ event = gdk_event_new (GDK_CONFIGURE); @@ -183,12 +184,13 @@ _gdk_event_queue_append (gdk_display_get_default (), event); } --(id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag +-(id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen { self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType - defer:flag]; + defer:flag + screen:screen]; [self setAcceptsMouseMovedEvents:YES]; [self setDelegate:self]; @@ -506,16 +508,18 @@ update_context_from_dragging_info (id sender) NSPoint point = [sender draggingLocation]; NSPoint screen_point = [self convertBaseToScreen:point]; GdkEvent event; + int gx, gy; update_context_from_dragging_info (sender); + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy); event.dnd.type = GDK_DRAG_MOTION; event.dnd.window = g_object_ref ([[self contentView] gdkWindow]); event.dnd.send_event = FALSE; event.dnd.context = current_context; event.dnd.time = GDK_CURRENT_TIME; - event.dnd.x_root = screen_point.x; - event.dnd.y_root = _gdk_quartz_window_get_inverted_screen_y (screen_point.y); + event.dnd.x_root = gx; + event.dnd.y_root = gy; (*_gdk_event_func) (&event, _gdk_event_data); @@ -529,16 +533,18 @@ update_context_from_dragging_info (id sender) NSPoint point = [sender draggingLocation]; NSPoint screen_point = [self convertBaseToScreen:point]; GdkEvent event; + int gy, gx; update_context_from_dragging_info (sender); + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy); event.dnd.type = GDK_DROP_START; event.dnd.window = g_object_ref ([[self contentView] gdkWindow]); event.dnd.send_event = FALSE; event.dnd.context = current_context; event.dnd.time = GDK_CURRENT_TIME; - event.dnd.x_root = screen_point.x; - event.dnd.y_root = _gdk_quartz_window_get_inverted_screen_y (screen_point.y); + event.dnd.x_root = gx; + event.dnd.y_root = gy; (*_gdk_event_func) (&event, _gdk_event_data); diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c index 54baef7f52..24044b355c 100644 --- a/gdk/quartz/gdkevents-quartz.c +++ b/gdk/quartz/gdkevents-quartz.c @@ -465,8 +465,7 @@ find_window_for_ns_event (NSEvent *nsevent, *x = point.x; *y = private->height - point.y; - *x_root = screen_point.x; - *y_root = _gdk_quartz_window_get_inverted_screen_y (screen_point.y); + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, x_root, y_root); event_type = [nsevent type]; diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h index 52834b36d5..258d1f8c70 100644 --- a/gdk/quartz/gdkprivate-quartz.h +++ b/gdk/quartz/gdkprivate-quartz.h @@ -138,7 +138,17 @@ void _gdk_quartz_colormap_get_rgba_from_pixel (GdkColormap *colormap, /* Window */ gboolean _gdk_quartz_window_is_ancestor (GdkWindow *ancestor, GdkWindow *window); -gint _gdk_quartz_window_get_inverted_screen_y (gint y); +void _gdk_quartz_window_gdk_xy_to_xy (gint gdk_x, + gint gdk_y, + gint *ns_x, + gint *ns_y); +void _gdk_quartz_window_xy_to_gdk_xy (gint ns_x, + gint ns_y, + gint *gdk_x, + gint *gdk_y); +void _gdk_quartz_window_nspoint_to_gdk_xy (NSPoint point, + gint *x, + gint *y); GdkWindow *_gdk_quartz_window_find_child (GdkWindow *window, gint x, gint y); diff --git a/gdk/quartz/gdkscreen-quartz.c b/gdk/quartz/gdkscreen-quartz.c index c9b45366e6..4afeb51975 100644 --- a/gdk/quartz/gdkscreen-quartz.c +++ b/gdk/quartz/gdkscreen-quartz.c @@ -129,6 +129,8 @@ gdk_screen_quartz_calculate_layout (GdkScreenQuartz *screen) */ screen->width = 0; screen->height = 0; + screen->min_x = 0; + screen->min_y = 0; for (i = 0; i < [array count]; i++) { @@ -136,6 +138,8 @@ gdk_screen_quartz_calculate_layout (GdkScreenQuartz *screen) screen->width += rect.size.width; screen->height = MAX (screen->height, rect.size.height); + screen->min_x = MIN (screen->min_x, rect.origin.x); + screen->min_y = MIN (screen->min_y, rect.origin.y); } screen->n_screens = [array count]; @@ -162,7 +166,7 @@ gdk_screen_quartz_calculate_layout (GdkScreenQuartz *screen) nsscreen = [array objectAtIndex:i]; rect = [nsscreen frame]; - screen->screen_rects[i].x = rect.origin.x; + screen->screen_rects[i].x = rect.origin.x - screen->min_x; screen->screen_rects[i].width = rect.size.width; screen->screen_rects[i].height = rect.size.height; diff --git a/gdk/quartz/gdkscreen-quartz.h b/gdk/quartz/gdkscreen-quartz.h index 370e876984..82da95cf1c 100644 --- a/gdk/quartz/gdkscreen-quartz.h +++ b/gdk/quartz/gdkscreen-quartz.h @@ -40,6 +40,10 @@ struct _GdkScreenQuartz GdkDisplay *display; GdkColormap *default_colormap; + /* Origin of "root window" in Cocoa coordinates */ + gint min_x; + gint min_y; + gint width; gint height; diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index 24057b50eb..f60cc79779 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -25,6 +25,7 @@ #include "gdk.h" #include "gdkwindowimpl.h" #include "gdkprivate-quartz.h" +#include "gdkscreen-quartz.h" #include "gdkinputprivate.h" static gpointer parent_class; @@ -557,6 +558,7 @@ _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number) { GdkWindowObject *private = GDK_WINDOW_OBJECT (window); gint x, y; + gint gx, gy; GdkWindow *toplevel; gint tx, ty; static NSWindow *debug_window[10]; @@ -585,9 +587,10 @@ _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number) x += tx; y += ty; - rect = NSMakeRect (x, - _gdk_quartz_window_get_inverted_screen_y (y + private->height), - private->width, private->height); + _gdk_quartz_window_gdk_xy_to_xy (x, y + private->height, + &gx, &gy); + + rect = NSMakeRect (gx, gy, private->width, private->height); if (debug_window[number] && NSEqualRects (rect, old_rect[number])) return; @@ -649,22 +652,44 @@ _gdk_quartz_window_is_ancestor (GdkWindow *ancestor, gdk_window_get_parent (window))); } -/* FIXME: It would be nice to have one function that takes an NSPoint - * and flips the coords for any window. - */ -gint -_gdk_quartz_window_get_inverted_screen_y (gint y) + +void +_gdk_quartz_window_gdk_xy_to_xy (gint gdk_x, + gint gdk_y, + gint *ns_x, + gint *ns_y) { - int index; - GdkRectangle gdk_rect; - NSScreen *main_screen = [NSScreen mainScreen]; - NSRect rect = [main_screen frame]; + GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen); - index = [[NSScreen screens] indexOfObject:main_screen]; + if (ns_y) + *ns_y = screen_quartz->height - gdk_y + screen_quartz->min_y; - gdk_screen_get_monitor_geometry (_gdk_screen, index, &gdk_rect); + if (ns_x) + *ns_x = gdk_x + screen_quartz->min_x; +} - return gdk_rect.height - y + rect.origin.y + gdk_rect.y; +void +_gdk_quartz_window_xy_to_gdk_xy (gint ns_x, + gint ns_y, + gint *gdk_x, + gint *gdk_y) +{ + GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen); + + if (gdk_y) + *gdk_y = screen_quartz->height - ns_y + screen_quartz->min_y; + + if (gdk_x) + *gdk_x = ns_x - screen_quartz->min_x; +} + +void +_gdk_quartz_window_nspoint_to_gdk_xy (NSPoint point, + gint *x, + gint *y) +{ + _gdk_quartz_window_xy_to_gdk_xy (point.x, point.y, + x, y); } static GdkWindow * @@ -780,8 +805,7 @@ generate_motion_event (GdkWindow *window) screen_point = [NSEvent mouseLocation]; - x_root = screen_point.x; - y_root = _gdk_quartz_window_get_inverted_screen_y (screen_point.y); + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &x_root, &y_root); point = [nswindow convertScreenToBase:screen_point]; @@ -860,6 +884,32 @@ _gdk_quartz_window_did_resign_main (GdkWindow *window) clear_toplevel_order (); } +static NSScreen * +get_nsscreen_for_x (gint x) +{ + int i; + NSArray *screens; + + GDK_QUARTZ_ALLOC_POOL; + + screens = [NSScreen screens]; + + for (i = 0; i < [screens count]; i++) + { + NSRect rect = [[screens objectAtIndex:i] frame]; + + /* FIXME: Only horizontal layouts supported for now. Also + * see comments in gdkscreen-quartz.c + */ + if (x >= rect.origin.x && x <= rect.origin.x + rect.size.width) + return [screens objectAtIndex:i]; + } + + GDK_QUARTZ_RELEASE_POOL; + + return NULL; +} + void _gdk_window_impl_new (GdkWindow *window, GdkWindow *real_parent, @@ -944,12 +994,26 @@ _gdk_window_impl_new (GdkWindow *window, case GDK_WINDOW_DIALOG: case GDK_WINDOW_TEMP: { + NSScreen *screen; + NSRect screen_rect; NSRect content_rect; int style_mask; + int nx, ny; const char *title; - content_rect = NSMakeRect (private->x, - _gdk_quartz_window_get_inverted_screen_y (private->y) - private->height, + /* initWithContentRect will place on the mainScreen by default. + * We want to select the screen to place on ourselves. We need + * to find the screen the window will be on and correct the + * content_rect coordinates to be relative to that screen. + */ + _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y, &nx, &ny); + + screen = get_nsscreen_for_x (nx); + screen_rect = [screen frame]; + nx -= screen_rect.origin.x; + ny -= screen_rect.origin.y; + + content_rect = NSMakeRect (nx, ny - private->height, private->width, private->height); @@ -969,7 +1033,8 @@ _gdk_window_impl_new (GdkWindow *window, impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect styleMask:style_mask backing:NSBackingStoreBuffered - defer:NO]; + defer:NO + screen:screen]; if (attributes_mask & GDK_WA_TITLE) title = attributes->title; @@ -1323,10 +1388,12 @@ move_resize_window_internal (GdkWindow *window, { NSRect content_rect; NSRect frame_rect; + gint gx, gy; - content_rect = NSMakeRect (private->x, - _gdk_quartz_window_get_inverted_screen_y (private->y + private->height), - private->width, private->height); + _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y + private->height, + &gx, &gy); + + content_rect = NSMakeRect (gx, gy, private->width, private->height); frame_rect = [impl->toplevel frameRectForContentRect:content_rect]; [impl->toplevel setFrame:frame_rect display:YES]; @@ -1714,10 +1781,9 @@ gdk_window_quartz_get_geometry (GdkWindow *window, */ if ([impl->toplevel styleMask] == NSBorderlessWindowMask) { - if (x) - *x = ns_rect.origin.x; - if (y) - *y = _gdk_quartz_window_get_inverted_screen_y (ns_rect.origin.y + ns_rect.size.height); + _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x, + ns_rect.origin.y + ns_rect.size.height, + x, y); } else { @@ -1790,8 +1856,12 @@ gdk_window_quartz_get_root_coords (GdkWindow *window, content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]]; - tmp_x = x + content_rect.origin.x; - tmp_y = y + _gdk_quartz_window_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height); + _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x, + content_rect.origin.y + content_rect.size.height, + &tmp_x, &tmp_y); + + tmp_x += x; + tmp_y += y; while (private != GDK_WINDOW_OBJECT (toplevel)) { @@ -1870,8 +1940,7 @@ gdk_window_quartz_get_pointer_helper (GdkWindow *window, if (window == _gdk_root) { point = [NSEvent mouseLocation]; - x_tmp = point.x; - y_tmp = _gdk_quartz_window_get_inverted_screen_y (point.y); + _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp); } else { @@ -2525,8 +2594,10 @@ gdk_window_get_frame_extents (GdkWindow *window, ns_rect = [impl->toplevel frame]; - rect->x = ns_rect.origin.x; - rect->y = _gdk_quartz_window_get_inverted_screen_y (ns_rect.origin.y + ns_rect.size.height); + _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x, + ns_rect.origin.y + ns_rect.size.height, + &rect->x, &rect->y); + rect->width = ns_rect.size.width; rect->height = ns_rect.size.height; }