DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.
[STR New]
Link: http://www.fltk.org/str.php?L2697
Version: 1.3-current
Attached file "screens.patch"...
Link: http://www.fltk.org/str.php?L2697
Version: 1.3-current
Index: FL/mac.H
===================================================================
--- FL/mac.H (revision 9057)
+++ FL/mac.H (working copy)
@@ -125,6 +125,8 @@
static CGContextRef nwse_cursor_image(void);
static CGContextRef none_cursor_image(void);
static void *get_carbon_function(const char *name);
+ static void screen_work_area(int n, XRectangle *area); // compute work area
of a given screen
+ static void mac_screen_init(void); // recompute screen number and dimensions
private:
static void relink(Fl_Window*, Fl_Window*);
bool subwindow;
Index: FL/Fl.H
===================================================================
--- FL/Fl.H (revision 9039)
+++ FL/Fl.H (working copy)
@@ -757,13 +757,13 @@
fl global screen functions declared in <FL/Fl.H>
@{ */
// screen size:
- /** Returns the origin of the current screen work area, where 0 indicates
the left side of the screen. */
+ /** Returns the origin of the main screen work area, where 0 indicates the
left side of the screen. */
static int x(); // platform dependent
- /** Returns the origin of the current screen work area, where 0 indicates
the top edge of the screen. */
+ /** Returns the origin of the main screen work area, where 0 indicates the
top edge of the screen. */
static int y(); // platform dependent
- /** Returns the width of the screen work area in pixels. */
+ /** Returns the width of the main screen work area in pixels. */
static int w(); // platform dependent
- /** Returns the height of the screen work area in pixels. */
+ /** Returns the height of the main screen work area in pixels. */
static int h(); // platform dependent
// multi-head support:
@@ -780,6 +780,16 @@
static void screen_xywh(int &X, int &Y, int &W, int &H, int n);
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int
mw, int mh);
static void screen_dpi(float &h, float &v, int n=0);
+ static void work_area_xywh(int &X, int &Y, int &W, int &H, int mx, int my);
+ static void work_area_xywh(int &X, int &Y, int &W, int &H, int n);
+ /**
+ Gets the bounding box of the work area of the screen that contains the
mouse pointer.
+ \param[out] X,Y,W,H the work area bounding box
+ \see void work_area_xywh(int &x, int &y, int &w, int &h, int mx, int my)
+ */
+ static void work_area_xywh(int &X, int &Y, int &W, int &H) {
+ work_area_xywh(X, Y, W, H, e_x_root, e_y_root);
+ }
/** @} */
Index: src/screen_xywh.cxx
===================================================================
--- src/screen_xywh.cxx (revision 9039)
+++ src/screen_xywh.cxx (working copy)
@@ -47,6 +47,7 @@
static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for
GetMonitorInfoA
static RECT screens[16];
+static RECT work_area[16];
static float dpi[16][2];
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) {
@@ -60,8 +61,11 @@
if (fl_gmi(mon, &mi)) {
screens[num_screens] = mi.rcMonitor;
// If we also want to record the work area, we would also store mi.rcWork at
this point
-// work_area[num_screens] = mi.rcWork;
-
+ work_area[num_screens] = mi.rcWork;
+/*fl_alert("screen %d %d,%d,%d,%d work %d,%d,%d,%d",num_screens,
+
screens[num_screens].left,screens[num_screens].right,screens[num_screens].top,screens[num_screens].bottom,
+
work_area[num_screens].left,work_area[num_screens].right,work_area[num_screens].top,work_area[num_screens].bottom);
+*/
// find the pixel size
if (mi.cbSize == sizeof(mi)) {
HDC screen = CreateDC(mi.szDevice, NULL, NULL, NULL);
@@ -107,9 +111,11 @@
screens[0].left = 0;
screens[0].right = GetSystemMetrics(SM_CXSCREEN);
screens[0].bottom = GetSystemMetrics(SM_CYSCREEN);
+ work_area[0] = screens[0];
}
#elif defined(__APPLE__)
static XRectangle screens[16];
+static XRectangle work_area[16];
static float dpi_h[16];
static float dpi_v[16];
@@ -124,12 +130,25 @@
screens[i].y = int(r.origin.y);
screens[i].width = int(r.size.width);
screens[i].height = int(r.size.height);
- CGSize s = CGDisplayScreenSize(displays[i]);
- dpi_h[i] = screens[i].width / (s.width/25.4);
- dpi_v[i] = screens[i].height / (s.height/25.4);
+ Fl_X::screen_work_area(i, work_area + i);
+//fprintf(stderr,"screen %d
%dx%dx%dx%d\n",i,screens[i].x,screens[i].y,screens[i].width,screens[i].height);
+//fprintf(stderr,"workarea %d
%dx%dx%dx%d\n",i,work_area[i].x,work_area[i].y,work_area[i].width,work_area[i].height);
+ if (CGDisplayScreenSize != NULL) {
+ CGSize s = CGDisplayScreenSize(displays[i]); // from 10.3
+ dpi_h[i] = screens[i].width / (s.width/25.4);
+ dpi_v[i] = screens[i].height / (s.height/25.4);
+ }
+ else {
+ dpi_h[i] = dpi_v[i] = 75.;
+ }
}
num_screens = count;
}
+
+void Fl_X::mac_screen_init() {
+ screen_init();
+ }
+
#elif HAVE_XINERAMA
# include <X11/extensions/Xinerama.h>
@@ -207,7 +226,57 @@
screen_xywh(X, Y, W, H, screen);
}
+
/**
+ Gets the bounding box of the work area of a screen
+ that contains the specified screen position \p mx, \p my
+ \param[out] X,Y,W,H the work area bounding box
+ \param[in] mx, my the absolute screen position
+ */
+void Fl::work_area_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
+ int screen = 0;
+ int i;
+
+ if (num_screens < 0) screen_init();
+
+ for (i = 0; i < num_screens; i ++) {
+ int sx, sy, sw, sh;
+ Fl::screen_xywh(sx, sy, sw, sh, i);
+ if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) {
+ screen = i;
+ break;
+ }
+ }
+ work_area_xywh(X, Y, W, H, screen);
+}
+
+/**
+ Gets the bounding box of the work area of the given screen.
+ \param[out] X,Y,W,H the work area bounding box
+ \param[in] n the screen number (0 to Fl::screen_count() - 1)
+ \see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my)
+*/
+void Fl::work_area_xywh(int &X, int &Y, int &W, int &H, int n) {
+ if (num_screens < 0) screen_init();
+ if (n < 0 || n >= num_screens) n = 0;
+#ifdef WIN32
+ X = work_area[n].left;
+ Y = work_area[n].top;
+ W = work_area[n].right - X;
+ H = work_area[n].bottom - Y;
+#elif defined(__APPLE__)
+ X = work_area[n].x;
+ Y = work_area[n].y;
+ W = work_area[n].width;
+ H = work_area[n].height;
+#else
+ // I did not find an API to get the work area of a single display,
+ // return the whole screen area instead.
+ screen_xywh(X, Y, W, H, n);
+#endif
+}
+
+/**
Gets the screen bounding rect for the given screen.
\param[out] X,Y,W,H the corresponding screen bounding box
\param[in] n the screen number (0 to Fl::screen_count() - 1)
Index: src/Fl_Menu.cxx
===================================================================
--- src/Fl_Menu.cxx (revision 9039)
+++ src/Fl_Menu.cxx (working copy)
@@ -279,13 +279,7 @@
int scr_x, scr_y, scr_w, scr_h;
int tx = X, ty = Y;
- Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
-#ifdef __APPLE__
- scr_x = Fl::x();
- scr_w = Fl::w();
-#endif
- scr_y = Fl::y();
- scr_h = Fl::h();
+ Fl::work_area_xywh(scr_x, scr_y, scr_w, scr_h);
if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w;
end();
@@ -419,8 +413,8 @@
int scr_y, scr_h;
int Y = y()+Fl::box_dx(box())+2+n*itemheight;
- scr_y = Fl::y();
- scr_h = Fl::h();
+ int xx, ww;
+ Fl::work_area_xywh(xx, scr_y, ww, scr_h);
if (Y <= scr_y) Y = scr_y-Y+10;
else {
Y = Y+itemheight-scr_h-scr_y;
Index: src/Fl_x.cxx
===================================================================
--- src/Fl_x.cxx (revision 9039)
+++ src/Fl_x.cxx (working copy)
@@ -668,6 +668,8 @@
}
else
{
+ // returns the origin and size of the work area of the global screen
+ // (that encompasses all screens)
fl_workarea_xywh[0] = (int)xywh[0];
fl_workarea_xywh[1] = (int)xywh[1];
fl_workarea_xywh[2] = (int)xywh[2];
Index: src/Fl_cocoa.mm
===================================================================
--- src/Fl_cocoa.mm (revision 9050)
+++ src/Fl_cocoa.mm (working copy)
@@ -109,6 +109,7 @@
// forward declarations of variables in this file
static int got_events = 0;
static Fl_Window* resize_from_system;
+static int main_screen_height; // height of menubar-containing screen used to
convert between Cocoa and FLTK global screen coordinates
#if CONSOLIDATE_MOTION
static Fl_Window* send_motion;
@@ -675,6 +676,7 @@
return retval;
}
+
// updates Fl::e_x, Fl::e_y, Fl::e_x_root, and Fl::e_y_root
static void update_e_xy_and_e_xy_root(NSWindow *nsw)
{
@@ -684,7 +686,7 @@
Fl::e_y = int([[nsw contentView] frame].size.height - pt.y);
pt = [NSEvent mouseLocation];
Fl::e_x_root = int(pt.x);
- Fl::e_y_root = int([[nsw screen] frame].size.height - pt.y);
+ Fl::e_y_root = int(main_screen_height - pt.y);
}
/*
@@ -929,12 +931,16 @@
- (void)anywindowwillclosenotif:(NSNotification *)notif;
-
(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
- (void)applicationDidBecomeActive:(NSNotification *)notify;
+- (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification;
- (void)applicationWillResignActive:(NSNotification *)notify;
- (void)applicationWillHide:(NSNotification *)notify;
- (void)applicationWillUnhide:(NSNotification *)notify;
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client;
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString
*)filename;
@end
+
+static FLDelegate *mydelegate;
+
@implementation FLDelegate
- (void)windowDidMove:(NSNotification *)notif
{
@@ -946,7 +952,7 @@
pt.y = [[nsw contentView] frame].size.height;
pt2 = [nsw convertBaseToScreen:pt];
update_e_xy_and_e_xy_root(nsw);
- window->position((int)pt2.x, (int)([[nsw screen] frame].size.height -
pt2.y));
+ window->position((int)pt2.x, (int)(main_screen_height - pt2.y));
if ([nsw containsGLsubwindow] ) {
[nsw display];// redraw window after moving if it contains OpenGL
subwindows
}
@@ -965,7 +971,7 @@
resize_from_system = window;
update_e_xy_and_e_xy_root(nsw);
window->resize((int)pt2.x,
- (int)([[nsw screen] frame].size.height - pt2.y),
+ (int)(main_screen_height - pt2.y),
(int)r.size.width,
(int)r.size.height);
fl_unlock_function();
@@ -1092,6 +1098,21 @@
}
fl_unlock_function();
}
+- (void)applicationDidChangeScreenParameters:(NSNotification *)unused
+{ // react to changes in screen numbers and positions
+ main_screen_height = [[[NSScreen screens] objectAtIndex:0]
frame].size.height;
+ Fl_X::mac_screen_init();
+ // react as though all windows were moved
+ NSArray *windows = [NSApp windows];
+ int count = [windows count];
+ for (int i = 0; i < count; i++) {
+ NSWindow *win = [windows objectAtIndex:i];
+ if ([win isKindOfClass:[FLWindow class]]) {
+ NSNotification *notif = [NSNotification
notificationWithName:NSWindowDidMoveNotification object:win];
+ [mydelegate windowDidMove:notif];
+ }
+ }
+}
- (void)applicationWillResignActive:(NSNotification *)notify
{
fl_lock_function();
@@ -1213,8 +1234,6 @@
}
@end
-static FLDelegate *mydelegate;
-
void fl_open_display() {
static char beenHereDoneThat = 0;
if ( !beenHereDoneThat ) {
@@ -1289,6 +1308,7 @@
selector:@selector(anywindowwillclosenotif:)
name:NSWindowWillCloseNotification
object:nil];
+ [mydelegate applicationDidChangeScreenParameters:nil];
}
}
@@ -1319,38 +1339,46 @@
}
/*
- * smallest x ccordinate in screen space
+ * smallest x coordinate in screen space of work area of menubar-containing
display
*/
int Fl::x() {
- return int([[NSScreen mainScreen] visibleFrame].origin.x);
+ return int([[[NSScreen screens] objectAtIndex:0] visibleFrame].origin.x);
}
/*
- * smallest y coordinate in screen space
+ * smallest y coordinate in screen space of work area of menubar-containing
display
*/
int Fl::y() {
- NSRect all = [[NSScreen mainScreen] frame];
- NSRect visible = [[NSScreen mainScreen] visibleFrame];
- return int(all.size.height - (visible.origin.y + visible.size.height));
+ NSRect visible = [[[NSScreen screens] objectAtIndex:0] visibleFrame];
+ return int(main_screen_height - (visible.origin.y + visible.size.height));
}
/*
- * screen width
+ * width of work area of menubar-containing display
*/
int Fl::w() {
- return int([[NSScreen mainScreen] visibleFrame].size.width);
+ return int([[[NSScreen screens] objectAtIndex:0] visibleFrame].size.width);
}
/*
- * screen height
+ * height of work area of menubar-containing display
*/
int Fl::h() {
- return int([[NSScreen mainScreen] visibleFrame].size.height);
+ return int([[[NSScreen screens] objectAtIndex:0] visibleFrame].size.height);
}
+// computes the work area of the nth screen (screen #0 has the menubar)
+void Fl_X::screen_work_area(int n, XRectangle *work)
+{
+ NSRect r = [[[NSScreen screens] objectAtIndex:n] visibleFrame];
+ work->x = int(r.origin.x);
+ work->y = main_screen_height - int(r.origin.y + r.size.height);
+ work->width = int(r.size.width);
+ work->height = int(r.size.height);
+}
/*
* get the current mouse pointer world coordinates
@@ -1360,7 +1388,7 @@
fl_open_display();
NSPoint pt = [NSEvent mouseLocation];
x = int(pt.x);
- y = int([[NSScreen mainScreen] frame].size.height - pt.y);
+ y = int(main_screen_height - pt.y);
}
@@ -1438,7 +1466,7 @@
NSArray *a = [NSScreen screens]; int count = (int)[a count]; NSRect r; int i;
for( i = 0; i < count; i++) {
r = [[a objectAtIndex:i] frame];
- cy = int(r.size.height - cy);
+ r.origin.y = main_screen_height - (r.origin.y + r.size.height); // use
FLTK's multiscreen coordinates
if ( cx >= r.origin.x && cx <= r.origin.x + r.size.width
&& cy >= r.origin.y && cy <= r.origin.y + r.size.height)
break;
@@ -1449,8 +1477,9 @@
if (!gd) {
for( i = 0; i < count; i++) {
r = [[a objectAtIndex:i] frame];
+ r.origin.y = main_screen_height - (r.origin.y + r.size.height); // use
FLTK's multiscreen coordinates
if ( X >= r.origin.x && X <= r.origin.x + r.size.width
- && r.size.height - Y >= r.origin.y && r.size.height - Y <=
r.origin.y + r.size.height)
+ && Y >= r.origin.y && Y <= r.origin.y + r.size.height)
break;
}
if (i < count) gd = [a objectAtIndex:i];
@@ -1459,8 +1488,9 @@
if (!gd) {
for( i = 0; i < count; i++) {
r = [[a objectAtIndex:i] frame];
+ r.origin.y = main_screen_height - (r.origin.y + r.size.height); // use
FLTK's multiscreen coordinates
if ( R >= r.origin.x && R <= r.origin.x + r.size.width
- && r.size.height - Y >= r.origin.y && r.size.height - Y <=
r.origin.y + r.size.height)
+ && Y >= r.origin.y && Y <= r.origin.y + r.size.height)
break;
}
if (i < count) gd = [a objectAtIndex:i];
@@ -1469,8 +1499,9 @@
if (!gd) {
for( i = 0; i < count; i++) {
r = [[a objectAtIndex:i] frame];
+ r.origin.y = main_screen_height - (r.origin.y + r.size.height); // use
FLTK's multiscreen coordinates
if ( X >= r.origin.x && X <= r.origin.x + r.size.width
- && Y-H >= r.origin.y && Y-H <= r.origin.y + r.size.height)
+ && Y+H >= r.origin.y && Y+H <= r.origin.y + r.size.height)
break;
}
if (i < count) gd = [a objectAtIndex:i];
@@ -1479,8 +1510,9 @@
if (!gd) {
for( i = 0; i < count; i++) {
r = [[a objectAtIndex:i] frame];
+ r.origin.y = main_screen_height - (r.origin.y + r.size.height); // use
FLTK's multiscreen coordinates
if ( R >= r.origin.x && R <= r.origin.x + r.size.width
- && Y-H >= r.origin.y && Y-H <= r.origin.y + r.size.height)
+ && Y+H >= r.origin.y && Y+H <= r.origin.y + r.size.height)
break;
}
if (i < count) gd = [a objectAtIndex:i];
@@ -1490,11 +1522,11 @@
if (!gd) gd = [a objectAtIndex:0];
if (gd) {
r = [gd visibleFrame];
- int sh = int([gd frame].size.height);
+ r.origin.y = main_screen_height - (r.origin.y + r.size.height); // use
FLTK's multiscreen coordinates
if ( R > r.origin.x + r.size.width ) X -= int(R - (r.origin.x +
r.size.width));
- if ( B > sh - r.origin.y ) Y -= int(B - (sh - r.origin.y));
+ if ( B > r.size.height + r.origin.y ) Y -= int(B - (r.size.height +
r.origin.y));
if ( X < r.origin.x ) X = int(r.origin.x);
- if ( Y < sh - (r.origin.y + r.size.height) ) Y = int(sh - (r.origin.y +
r.size.height));
+ if ( Y < r.origin.y ) Y = int(r.origin.y);
}
// Return the client area's top left corner in (X,Y)
@@ -2054,10 +2086,9 @@
x->xidNext = 0;
x->gc = 0;
- NSRect srect = [[NSScreen mainScreen] frame];
NSRect crect;
crect.origin.x = w->x();
- crect.origin.y = srect.size.height - (w->y() + w->h());
+ crect.origin.y = main_screen_height - (w->y() + w->h());
crect.size.width=w->w();
crect.size.height=w->h();
FLWindow *cw = [[FLWindow alloc] initWithFl_W:w
@@ -2118,8 +2149,7 @@
w->h(int(crect.size.height));
crect = [cw frame];
w->x(int(crect.origin.x));
- srect = [[cw screen] frame];
- w->y(int(srect.size.height - (crect.origin.y + w->h())));
+ w->y(int(main_screen_height - (crect.origin.y + w->h())));
int old_event = Fl::e_number;
w->handle(Fl::e_number = FL_SHOW);
@@ -2235,14 +2265,14 @@
else get_window_frame_sizes(bx, by, bt);
NSRect dim;
dim.origin.x = X;
- dim.origin.y = [[(NSWindow*)i->xid screen] frame].size.height - (Y + H);
+ dim.origin.y = main_screen_height - (Y + H);
dim.size.width = W;
dim.size.height = H + bt;
[(NSWindow*)i->xid setFrame:dim display:YES];
} else {
NSPoint pt;
pt.x = X;
- pt.y = [[(NSWindow*)i->xid screen] frame].size.height - (Y + h());
+ pt.y = main_screen_height - (Y + h());
[(NSWindow*)i->xid setFrameOrigin:pt];
}
}
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs