summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl.H18
-rw-r--r--FL/mac.H2
-rw-r--r--src/Fl_Menu.cxx12
-rw-r--r--src/Fl_cocoa.mm118
-rw-r--r--src/Fl_x.cxx15
-rw-r--r--src/screen_xywh.cxx100
6 files changed, 171 insertions, 94 deletions
diff --git a/FL/Fl.H b/FL/Fl.H
index 634545fb6..ed6b7c56b 100644
--- a/FL/Fl.H
+++ b/FL/Fl.H
@@ -757,13 +757,13 @@ public:
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 leftmost x coordinate of the main screen work area. */
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 topmost y coordinate of the main screen work area. */
static int y(); // platform dependent
- /** Returns the width of the screen work area in pixels. */
+ /** Returns the width in pixels of the main screen work area. */
static int w(); // platform dependent
- /** Returns the height of the screen work area in pixels. */
+ /** Returns the height in pixels of the main screen work area. */
static int h(); // platform dependent
// multi-head support:
@@ -780,6 +780,16 @@ public:
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 screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my);
+ static void screen_work_area(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 screen_work_area(int &x, int &y, int &w, int &h, int mx, int my)
+ */
+ static void screen_work_area(int &X, int &Y, int &W, int &H) {
+ screen_work_area(X, Y, W, H, e_x_root, e_y_root);
+ }
/** @} */
diff --git a/FL/mac.H b/FL/mac.H
index 573ebe936..c53824ea7 100644
--- a/FL/mac.H
+++ b/FL/mac.H
@@ -125,6 +125,8 @@ public:
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 &X, int &Y, int &W, int &H, int n); // 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;
diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx
index 1162c0238..224645b95 100644
--- a/src/Fl_Menu.cxx
+++ b/src/Fl_Menu.cxx
@@ -276,13 +276,7 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
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::screen_work_area(scr_x, scr_y, scr_w, scr_h);
if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w;
end();
@@ -417,8 +411,8 @@ void menuwindow::autoscroll(int n) {
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::screen_work_area(xx, scr_y, ww, scr_h);
if (Y <= scr_y) Y = scr_y-Y+10;
else {
Y = Y+itemheight-scr_h-scr_y;
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index c15730d45..801c848c2 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -109,6 +109,7 @@ int fl_mac_os_version = 0; // the version number of the running Mac OS X (e.g.,
// 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 @@ double fl_mac_flush_and_wait(double time_to_wait, char in_idle) {
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 @@ static void update_e_xy_and_e_xy_root(NSWindow *nsw)
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);
}
/*
@@ -902,16 +904,6 @@ void fl_open_callback(void (*cb)(const char *)) {
}
-/*
- * initialize the Mac toolboxes, dock status, and set the default menubar
- */
-
-extern "C" {
- extern OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2,
- UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-}
-
-
@interface FLDelegate : NSObject
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
<NSWindowDelegate, NSApplicationDelegate>
@@ -929,6 +921,7 @@ extern "C" {
- (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;
@@ -946,7 +939,7 @@ extern "C" {
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 +958,7 @@ extern "C" {
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 +1085,21 @@ extern "C" {
}
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();
+ // FLTK windows have already been notified they were moved,
+ // but they had the old main_screen_height, so they must be notified again.
+ 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]]) {
+ [[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidMoveNotification object:win];
+ }
+ }
+}
- (void)applicationWillResignActive:(NSNotification *)notify
{
fl_lock_function();
@@ -1213,7 +1221,10 @@ extern "C" {
}
@end
-static FLDelegate *mydelegate;
+extern "C" {
+ OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2,
+ UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+}
void fl_open_display() {
static char beenHereDoneThat = 0;
@@ -1224,8 +1235,7 @@ void fl_open_display() {
if (need_new_nsapp) [NSApplication sharedApplication];
NSAutoreleasePool *localPool;
localPool = [[NSAutoreleasePool alloc] init]; // never released
- mydelegate = [[FLDelegate alloc] init];
- [NSApp setDelegate:mydelegate];
+ [NSApp setDelegate:[[FLDelegate alloc] init]];
if (need_new_nsapp) [NSApp finishLaunching];
// empty the event queue but keep system events for drag&drop of files at launch
@@ -1266,17 +1276,12 @@ void fl_open_display() {
// both TransformProcessType and CPSEnableForegroundOperation, the following
// conditional code compiled on 10.2 will still work on newer releases...
OSErr err;
-#if __LP64__
- err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication);
-#else
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
if (TransformProcessType != NULL) {
err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication);
} else
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103);
-#endif // __LP64__
if (err == noErr) {
SetFrontProcess( &cur_psn );
}
@@ -1285,10 +1290,11 @@ void fl_open_display() {
if (![NSApp servicesMenu]) createAppleMenu();
fl_system_menu = [NSApp mainMenu];
- [[NSNotificationCenter defaultCenter] addObserver:mydelegate
+ [[NSNotificationCenter defaultCenter] addObserver:[NSApp delegate]
selector:@selector(anywindowwillclosenotif:)
name:NSWindowWillCloseNotification
object:nil];
+ [[NSNotificationCenter defaultCenter] postNotificationName:NSApplicationDidChangeScreenParametersNotification object:NSApp];
}
}
@@ -1319,38 +1325,46 @@ static void get_window_frame_sizes(int &bx, int &by, int &bt) {
}
/*
- * 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 &X, int &Y, int &W, int &H, int n)
+{
+ NSRect r = [[[NSScreen screens] objectAtIndex:n] visibleFrame];
+ X = int(r.origin.x);
+ Y = main_screen_height - int(r.origin.y + r.size.height);
+ W = int(r.size.width);
+ H = int(r.size.height);
+}
/*
* get the current mouse pointer world coordinates
@@ -1360,7 +1374,7 @@ void Fl::get_mouse(int &x, int &y)
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 +1452,7 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
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 +1463,9 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
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 +1474,9 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
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 +1485,9 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
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 +1496,9 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
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 +1508,11 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
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)
@@ -2024,7 +2042,7 @@ void Fl_X::make(Fl_Window* w)
hp += 2*by+bt;
}
if (!(w->flags() & Fl_Window::FORCE_POSITION)) {
- // use the Carbon functions below for default window positioning
+ // default window positioning on the main screen
w->x(xyPos+Fl::x());
w->y(xyPos+Fl::y());
xyPos += 25;
@@ -2054,10 +2072,9 @@ void Fl_X::make(Fl_Window* w)
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
@@ -2105,7 +2122,7 @@ void Fl_X::make(Fl_Window* w)
w->set_visible();
if ( w->border() || (!w->modal() && !w->tooltip_window()) ) Fl::handle(FL_FOCUS, w);
Fl::first_window(w);
- [cw setDelegate:mydelegate];
+ [cw setDelegate:[NSApp delegate]];
if (fl_show_iconic) {
fl_show_iconic = 0;
[cw miniaturize:nil];
@@ -2118,8 +2135,7 @@ void Fl_X::make(Fl_Window* w)
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 +2251,14 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
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];
}
}
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index fe98cd1d9..bc528aa34 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -655,16 +655,21 @@ static void fl_init_workarea() {
int format;
unsigned *xywh;
- if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
+ /* If there are several screens, the _NET_WORKAREA property
+ does not give the work area of the main screen, but that of all screens together.
+ Therefore, we use this property only when there is a single screen,
+ and fall back to the main screen full area when there are several screens.
+ */
+ if (Fl::screen_count() > 1 || XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
_NET_WORKAREA, 0, 4 * sizeof(unsigned), False,
XA_CARDINAL, &actual, &format, &count, &remaining,
(unsigned char **)&xywh) || !xywh || !xywh[2] ||
!xywh[3])
{
- fl_workarea_xywh[0] = 0;
- fl_workarea_xywh[1] = 0;
- fl_workarea_xywh[2] = DisplayWidth(fl_display, fl_screen);
- fl_workarea_xywh[3] = DisplayHeight(fl_display, fl_screen);
+ Fl::screen_xywh(fl_workarea_xywh[0],
+ fl_workarea_xywh[1],
+ fl_workarea_xywh[2],
+ fl_workarea_xywh[3], 0);
}
else
{
diff --git a/src/screen_xywh.cxx b/src/screen_xywh.cxx
index 9ceb8630e..878b9bf9a 100644
--- a/src/screen_xywh.cxx
+++ b/src/screen_xywh.cxx
@@ -47,6 +47,7 @@ typedef BOOL (WINAPI* fl_gmi_func)(HMONITOR, LPMONITORINFO);
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 @@ static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) {
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,6 +111,7 @@ static void screen_init() {
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];
@@ -124,12 +129,23 @@ static void screen_init() {
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);
+//fprintf(stderr,"screen %d %dx%dx%dx%d\n",i,screens[i].x,screens[i].y,screens[i].width,screens[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>
@@ -183,19 +199,11 @@ int Fl::screen_count() {
return num_screens ? num_screens : 1;
}
-/**
- Gets the bounding box of a screen
- that contains the specified screen position \p mx, \p my
- \param[out] X,Y,W,H the corresponding screen bounding box
- \param[in] mx, my the absolute screen position
-*/
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
+static int find_screen_with_point(int mx, int my) {
int screen = 0;
- int i;
-
if (num_screens < 0) screen_init();
-
- for (i = 0; i < num_screens; i ++) {
+
+ for (int 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))) {
@@ -203,12 +211,62 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
break;
}
}
+ return screen;
+}
+
+/**
+ Gets the bounding box of a screen
+ that contains the specified screen position \p mx, \p my
+ \param[out] X,Y,W,H the corresponding screen bounding box
+ \param[in] mx, my the absolute screen position
+*/
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
+ screen_xywh(X, Y, W, H, find_screen_with_point(mx, my));
+}
- 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::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my) {
+ screen_work_area(X, Y, W, H, find_screen_with_point(mx, my));
+}
+
+/**
+ 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::screen_work_area(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__)
+ Fl_X::screen_work_area(X, Y, W, H, n);
+#else
+ if (n == 0) { // for the main screen, these return the work area
+ X = Fl::x();
+ Y = Fl::y();
+ W = Fl::w();
+ H = Fl::h();
+ }
+ else { // for other screens, work area is full screen,
+ screen_xywh(X, Y, W, H, n);
+ }
+#endif
}
/**
Gets the screen bounding rect for the given screen.
+ Under MSWindows, Mac OS X, and the Gnome desktop, screen #0 contains the menubar/taskbar
\param[out] X,Y,W,H the corresponding screen 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)
@@ -233,18 +291,10 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
H = GetSystemMetrics(SM_CYSCREEN);
}
#elif defined(__APPLE__)
- if (num_screens > 0) {
X = screens[n].x;
Y = screens[n].y;
W = screens[n].width;
H = screens[n].height;
- } else {
- /* Fallback if something is broken... */
- X = Fl::x();
- Y = Fl::y();
- W = Fl::w();
- H = Fl::h();
- }
#else
#if HAVE_XINERAMA
if (num_screens > 0 && screens) {