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

Reply via email to