Author: manolo
Date: 2011-09-30 09:19:31 -0700 (Fri, 30 Sep 2011)
New Revision: 9103
Log:
Backport of changes to 1.3 until Sep 30, 2011.
Modified:
branches/branch-3.0/include/fltk3/enumerations.h
branches/branch-3.0/include/fltk3/osx.h
branches/branch-3.0/include/fltk3/run.h
branches/branch-3.0/src/fltk3/Menu.cxx
branches/branch-3.0/src/fltk3/cocoa.mm
branches/branch-3.0/src/fltk3/rect.cxx
branches/branch-3.0/src/fltk3/run.cxx
branches/branch-3.0/src/fltk3/screen_xywh.cxx
branches/branch-3.0/src/fltk3/win32.cxx
branches/branch-3.0/src/fltk3/x11.cxx
Modified: branches/branch-3.0/include/fltk3/enumerations.h
===================================================================
--- branches/branch-3.0/include/fltk3/enumerations.h 2011-09-30 14:46:08 UTC
(rev 9102)
+++ branches/branch-3.0/include/fltk3/enumerations.h 2011-09-30 16:19:31 UTC
(rev 9103)
@@ -294,7 +294,11 @@
If the widget returns 1, it will receive the data in the immediately
following fltk3::PASTE event.
*/
- DND_RELEASE = 23
+ DND_RELEASE = 23,
+ /** The screen configuration (number, positions) was changed.
+ Use fltk3::add_handler() to be notified of this event.
+ */
+ SCREEN_CONFIGURATION_CHANGED = 24
};
Modified: branches/branch-3.0/include/fltk3/osx.h
===================================================================
--- branches/branch-3.0/include/fltk3/osx.h 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/include/fltk3/osx.h 2011-09-30 16:19:31 UTC (rev
9103)
@@ -139,6 +139,7 @@
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
private:
static void relink(fltk3::Window*, fltk3::Window*);
bool subwindow;
Modified: branches/branch-3.0/include/fltk3/run.h
===================================================================
--- branches/branch-3.0/include/fltk3/run.h 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/include/fltk3/run.h 2011-09-30 16:19:31 UTC (rev
9103)
@@ -137,6 +137,7 @@
extern fltk3::Window* modal_;
extern fltk3::Window* grab_;
extern int compose_state;
+ void call_screen_init(); // recompute screen number and dimensions
#endif
/**
If true then flush() will do something.
@@ -761,14 +762,14 @@
fl global screen functions declared in <fltk3/run.h>
@{ */
// screen size:
- /** Returns the origin of the current screen work area, where 0 indicates
the left side of the screen. */
- int x(); // platform dependent
- /** Returns the origin of the current screen work area, where 0 indicates
the top edge of the screen. */
- int y(); // platform dependent
- /** Returns the width of the screen work area in pixels. */
- int w(); // platform dependent
- /** Returns the height of the screen work area in pixels. */
- int h(); // platform dependent
+ /** Returns the leftmost x coordinate of the main screen work area. */
+ int x();
+ /** Returns the topmost y coordinate of the main screen work area. */
+ int y();
+ /** Returns the width in pixels of the main screen work area. */
+ int w();
+ /** Returns the height in pixels of the main screen work area. */
+ int h();
// multi-head support:
int screen_count();
@@ -784,6 +785,16 @@
inline void screen_xywh(int &X, int &Y, int &W, int &H) {
screen_xywh(X, Y, W, H, e_x_root, e_y_root);
}
+ void screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my);
+ 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)
+ */
+ inline 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);
+ }
/** @} */
Modified: branches/branch-3.0/src/fltk3/Menu.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/Menu.cxx 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/src/fltk3/Menu.cxx 2011-09-30 16:19:31 UTC (rev
9103)
@@ -285,7 +285,7 @@
int scr_x, scr_y, scr_w, scr_h;
int tx = X, ty = Y;
- fltk3::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+ fltk3::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();
@@ -420,7 +420,7 @@
int scr_x, scr_y, scr_w, scr_h;
int Y = y()+fltk3::box_dx(box())+2+n*itemheight;
- fltk3::screen_xywh(scr_x, scr_y, scr_w, scr_h);
+ fltk3::screen_work_area(scr_x, scr_y, scr_w, scr_h);
if (Y <= scr_y) Y = scr_y-Y+10;
else {
Y = Y+itemheight-scr_h-scr_y;
Modified: branches/branch-3.0/src/fltk3/cocoa.mm
===================================================================
--- branches/branch-3.0/src/fltk3/cocoa.mm 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/src/fltk3/cocoa.mm 2011-09-30 16:19:31 UTC (rev
9103)
@@ -110,6 +110,7 @@
// forward declarations of variables in this file
static int got_events = 0;
static fltk3::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 fltk3::Window* send_motion;
@@ -685,7 +686,7 @@
fltk3::e_y = int([[nsw contentView] frame].size.height - pt.y);
pt = [NSEvent mouseLocation];
fltk3::e_x_root = int(pt.x);
- fltk3::e_y_root = int([[nsw screen] frame].size.height - pt.y);
+ fltk3::e_y_root = int(main_screen_height - pt.y);
}
/*
@@ -904,16 +905,6 @@
}
-/*
- * 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>
@@ -931,6 +922,7 @@
- (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;
@@ -948,7 +940,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
}
@@ -967,7 +959,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();
@@ -1094,6 +1086,22 @@
}
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;
+ fltk3::call_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];
+ }
+ }
+ fltk3::handle(fltk3::SCREEN_CONFIGURATION_CHANGED, NULL);
+}
- (void)applicationWillResignActive:(NSNotification *)notify
{
fl_lock_function();
@@ -1215,7 +1223,10 @@
}
@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;
@@ -1226,8 +1237,7 @@
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
@@ -1268,17 +1278,12 @@
// 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 );
}
@@ -1287,10 +1292,11 @@
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];
}
}
@@ -1321,38 +1327,46 @@
}
/*
- * smallest x ccordinate in screen space
+ * smallest x coordinate in screen space of work area of menubar-containing
display
*/
int fltk3::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 fltk3::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 fltk3::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 fltk3::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
@@ -1362,7 +1376,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);
}
@@ -1440,7 +1454,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;
@@ -1451,8 +1465,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];
@@ -1461,8 +1476,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];
@@ -1471,8 +1487,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];
@@ -1481,8 +1498,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];
@@ -1492,11 +1510,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)
@@ -2031,7 +2049,7 @@
hp += 2*by+bt;
}
if (!(w->flags() & fltk3::Window::FORCE_POSITION)) {
- // use the Carbon functions below for default window positioning
+ // default window positioning on the main screen
w->x(xyPos+fltk3::x());
w->y(xyPos+fltk3::y());
xyPos += 25;
@@ -2061,10 +2079,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
@@ -2112,7 +2129,7 @@
w->set_visible();
if ( w->border() || (!w->modal() && !w->tooltip_window()) )
fltk3::handle(fltk3::FOCUS, w);
fltk3::first_window(w);
- [cw setDelegate:mydelegate];
+ [cw setDelegate:[NSApp delegate]];
if (fl_show_iconic) {
fl_show_iconic = 0;
[cw miniaturize:nil];
@@ -2125,8 +2142,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 = fltk3::e_number;
w->handle(fltk3::e_number = fltk3::SHOW);
@@ -2242,14 +2258,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];
}
}
@@ -3355,7 +3371,7 @@
// so a CGRect matches exactly what is denoted x,y,w,h for clipping purposes
CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h) {
- return CGRectMake(x, y, w - 1, h - 1);
+ return CGRectMake(x, y, w > 0 ? w - 0.9 : 0, h > 0 ? h - 0.9 : 0);
}
Window fl_xid(const fltk3::Window* w)
Modified: branches/branch-3.0/src/fltk3/rect.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/rect.cxx 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/src/fltk3/rect.cxx 2011-09-30 16:19:31 UTC (rev
9103)
@@ -197,7 +197,7 @@
rect.right = x + w; rect.bottom = y + h;
FillRect(fl_gc, &rect, fl_brush());
#elif defined(__APPLE_QUARTZ__)
- CGRect rect = CGRectMake(x, y, w-1, h-1);
+ CGRect rect = CGRectMake(x, y, w-0.9, h-0.9);
CGContextFillRect(fl_gc, rect);
#else
# error unsupported platform
Modified: branches/branch-3.0/src/fltk3/run.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/run.cxx 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/src/fltk3/run.cxx 2011-09-30 16:19:31 UTC (rev
9103)
@@ -789,6 +789,7 @@
- fltk3::SHORTCUT events that are not recognized by any widget.
This lets you provide global shortcut keys.
+ - fltk3::SCREEN_CONFIGURATION_CHANGED events.
- System events that FLTK does not recognize. See fl_xevent.
- \e Some other events when the widget FLTK selected returns
zero from its handle() method. Exactly which ones may change
Modified: branches/branch-3.0/src/fltk3/screen_xywh.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/screen_xywh.cxx 2011-09-30 14:46:08 UTC
(rev 9102)
+++ branches/branch-3.0/src/fltk3/screen_xywh.cxx 2011-09-30 16:19:31 UTC
(rev 9103)
@@ -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,7 +61,7 @@
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;
// find the pixel size
if (mi.cbSize == sizeof(mi)) {
@@ -107,6 +108,7 @@
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 +126,18 @@
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);
+ 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;
}
+
#elif HAVE_XINERAMA
# include <X11/extensions/Xinerama.h>
@@ -173,6 +181,11 @@
}
#endif // WIN32
+#ifndef FL_DOXYGEN
+void fltk3::call_screen_init() {
+ screen_init();
+}
+#endif
/**
Gets the number of available screens.
@@ -183,19 +196,11 @@
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 fltk3::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;
fltk3::screen_xywh(sx, sy, sw, sh, i);
if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) {
@@ -203,13 +208,61 @@
break;
}
}
-
- screen_xywh(X, Y, W, H, screen);
+ 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 fltk3::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));
+}
/**
+ 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 fltk3::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 fltk3::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)
@@ -234,18 +287,10 @@
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 = fltk3::x();
- Y = fltk3::y();
- W = fltk3::w();
- H = fltk3::h();
- }
#else
#if HAVE_XINERAMA
if (num_screens > 0 && screens) {
Modified: branches/branch-3.0/src/fltk3/win32.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/win32.cxx 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/src/fltk3/win32.cxx 2011-09-30 16:19:31 UTC (rev
9103)
@@ -1214,7 +1214,11 @@
// unclear on what is correct:
if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard();
return 1;}
-
+ case WM_DISPLAYCHANGE: // occurs when screen configuration (number,
position) changes
+ fltk3::call_screen_init();
+ fltk3::handle(fltk3::SCREEN_CONFIGURATION_CHANGED, NULL);
+ return 0;
+
default:
if (fltk3::handle(0,0)) return 0;
break;
Modified: branches/branch-3.0/src/fltk3/x11.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/x11.cxx 2011-09-30 14:46:08 UTC (rev
9102)
+++ branches/branch-3.0/src/fltk3/x11.cxx 2011-09-30 16:19:31 UTC (rev
9103)
@@ -53,6 +53,10 @@
# include <X11/Xlocale.h>
# include <X11/Xlib.h>
# include <X11/keysym.h>
+#ifdef HAVE_XRANDR
+#include <X11/extensions/Xrandr.h>
+static int randrEventBase = -1;
+#endif
static fltk3::XlibGraphicsDriver fl_xlib_driver;
static fltk3::DisplayDevice fl_xlib_display(&fl_xlib_driver);
@@ -649,6 +653,12 @@
#if !USE_COLORMAP
fltk3::visual(fltk3::RGB);
#endif
+#ifdef HAVE_XRANDR
+ int error_base;
+ if (XRRQueryExtension(d, &randrEventBase, &error_base))
+ XRRSelectInput(d, RootWindow(d, fl_screen), RRScreenChangeNotifyMask);
+ else randrEventBase = -1;
+#endif
}
void fl_close_display() {
@@ -667,16 +677,21 @@
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 (fltk3::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);
+ fltk3::screen_xywh(fl_workarea_xywh[0],
+ fl_workarea_xywh[1],
+ fl_workarea_xywh[2],
+ fl_workarea_xywh[3], 0);
}
else
{
@@ -928,6 +943,15 @@
if ( XFilterEvent((XEvent *)&xevent, 0) )
return(1);
+#ifdef HAVE_XRANDR
+ if( randrEventBase >= 0 && xevent.type == randrEventBase +
RRScreenChangeNotify) {
+ XRRUpdateConfiguration (&xevent);
+ fltk3::call_screen_init();
+ fl_init_workarea();
+ fltk3::handle(fltk3::SCREEN_CONFIGURATION_CHANGED, NULL);
+ }
+#endif
+
switch (xevent.type) {
case KeymapNotify:
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit