Added MacOS X monitor support.

Now use new screen_xywh() API for keeping things on the current screen.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4227 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Michael R Sweet
2005-03-31 20:31:39 +00:00
parent 3ec9646eea
commit 782abe6de6
8 changed files with 99 additions and 73 deletions
+7 -38
View File
@@ -239,27 +239,10 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
int menubar, int menubar_title, int right_edge) int menubar, int menubar_title, int right_edge)
: Fl_Menu_Window(X, Y, Wp, Hp, 0) : Fl_Menu_Window(X, Y, Wp, Hp, 0)
{ {
int scr_right = Fl::x() + Fl::w(); int scr_x, scr_y, scr_w, scr_h;
int scr_x = Fl::x();
#ifdef __APPLE__
GDHandle gd = 0L;
for ( gd = GetDeviceList(); gd; gd = GetNextDevice(gd) ) {
GDPtr gp = *gd;
if ( X >= gp->gdRect.left && X <= gp->gdRect.right
&& Y >= gp->gdRect.top && Y <= gp->gdRect.bottom)
break;
}
if ( !gd ) gd = GetMainDevice();
if ( gd ) {
// since the menu pops over everything, we use the screen
// bounds, right across the dock and menu bar
GDPtr gp = *gd;
scr_right = gp->gdRect.right;
scr_x = gp->gdRect.left;
}
#endif
if (!right_edge) right_edge = scr_right; Fl::screen_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(); end();
set_modal(); set_modal();
@@ -315,7 +298,7 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
if (Wp > W) W = Wp; if (Wp > W) W = Wp;
if (Wtitle > W) W = Wtitle; if (Wtitle > W) W = Wtitle;
if (!Wp) {if (X < scr_x) X = scr_x; if (X > scr_right-W) X= right_edge-W;} if (X < scr_x) X = scr_x; if (X > scr_x+scr_w-W) X= scr_x+scr_w-W;
x(X); w(W); x(X); w(W);
h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3); h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3);
if (selected >= 0) if (selected >= 0)
@@ -344,24 +327,10 @@ void menuwindow::position(int X, int Y) {
// scroll so item i is visible on screen // scroll so item i is visible on screen
void menuwindow::autoscroll(int n) { void menuwindow::autoscroll(int n) {
int scr_y = Fl::y(), scr_h = Fl::h(); int scr_x, scr_y, scr_w, scr_h;
int Y = y()+Fl::box_dx(box())+2+n*itemheight; int Y = y()+Fl::box_dx(box())+2+n*itemheight;
#ifdef __APPLE__
GDHandle gd = 0L; Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
for ( gd = GetDeviceList(); gd; gd = GetNextDevice(gd) ) {
GDPtr gp = *gd;
if ( x() >= gp->gdRect.left && x() <= gp->gdRect.right
&& Y >= gp->gdRect.top && Y <= gp->gdRect.bottom)
break;
}
if ( !gd ) gd = GetMainDevice();
if ( gd ) {
// since the menu pops over everything, we use the screen
// bounds, right across the dock and menu bar
GDPtr gp = *gd;
scr_y = gp->gdRect.top; scr_h = gp->gdRect.bottom - gp->gdRect.top + 1;
}
#endif
if (Y <= scr_y) Y = scr_y-Y+10; if (Y <= scr_y) Y = scr_y-Y+10;
else { else {
Y = Y+itemheight-scr_h-scr_y; Y = Y+itemheight-scr_h-scr_y;
+7 -5
View File
@@ -75,15 +75,17 @@ void Fl_TooltipBox::layout() {
//ox += p->x(); //ox += p->x();
oy += p->y(); oy += p->y();
} }
if (ox+ww > Fl::w()) ox = Fl::w() - ww; int scr_x, scr_y, scr_w, scr_h;
if (ox < 0) ox = 0; Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
if (ox+ww > scr_x+scr_w) ox = scr_x+scr_w - ww;
if (ox < scr_x) ox = scr_x;
if (H > 30) { if (H > 30) {
oy = Fl::event_y_root()+13; oy = Fl::event_y_root()+13;
if (oy+hh > Fl::h()) oy -= 23+hh; if (oy+hh > scr_y+scr_h) oy -= 23+hh;
} else { } else {
if (oy+hh > Fl::h()) oy -= (4+hh+H); if (oy+hh > scr_y+scr_h) oy -= (4+hh+H);
} }
if (oy < 0) oy = 0; if (oy < scr_y) oy = scr_y;
resize(ox, oy, ww, hh); resize(ox, oy, ww, hh);
} }
+11 -8
View File
@@ -46,6 +46,9 @@ void Fl_Window::hotspot(int X, int Y, int offscreen) {
//force FL_FORCE_POSITION to be set in Fl_Window::resize() //force FL_FORCE_POSITION to be set in Fl_Window::resize()
if (X==x()) x(X-1); if (X==x()) x(X-1);
#else #else
int scr_x, scr_y, scr_w, scr_h;
Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
if (border()) { if (border()) {
// Ensure border is on screen; these values are generic enough // Ensure border is on screen; these values are generic enough
// to work with many window managers, and are based on KDE defaults. // to work with many window managers, and are based on KDE defaults.
@@ -53,16 +56,16 @@ void Fl_Window::hotspot(int X, int Y, int offscreen) {
const int left = 4; const int left = 4;
const int right = 4; const int right = 4;
const int bottom = 8; const int bottom = 8;
if (X+w()+right > Fl::w()-Fl::x()) X = Fl::w()-Fl::x()-right-w(); if (X+w()+right > scr_w-scr_x) X = scr_w-scr_x-right-w();
if (X-left < Fl::x()) X = left; if (X-left < scr_x) X = left;
if (Y+h()+bottom > Fl::h()-Fl::y()) Y = Fl::h()-Fl::y()-bottom-h(); if (Y+h()+bottom > scr_h-scr_y) Y = scr_h-scr_y-bottom-h();
if (Y-top < Fl::y()) Y = top; if (Y-top < scr_y) Y = top;
} }
// now insure contents are on-screen (more important than border): // now insure contents are on-screen (more important than border):
if (X+w() > Fl::w()-Fl::x()) X = Fl::w()-Fl::x()-w(); if (X+w() > scr_w-scr_x) X = scr_w-scr_x-w();
if (X < Fl::x()) X = Fl::x(); if (X < scr_x) X = scr_x;
if (Y+h() > Fl::h()-Fl::y()) Y = Fl::h()-Fl::y()-h(); if (Y+h() > scr_h-scr_y) Y = scr_h-scr_y-h();
if (Y < Fl::y()) Y = Fl::y(); if (Y < scr_y) Y = scr_y;
#endif #endif
} }
+10 -8
View File
@@ -913,17 +913,19 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
//Proceed to positioning the window fully inside the screen, if possible //Proceed to positioning the window fully inside the screen, if possible
//Make border's lower right corner visible //Make border's lower right corner visible
if (Fl::w() < X+W) X = Fl::w() - W; int scr_x, scr_y, scr_w, scr_h;
if (Fl::h() < Y+H) Y = Fl::h() - H; Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
if (scr_x+scr_w < X+W) X = scr_x+scr_x- W;
if (scr_y+scr_h < Y+H) Y = scr_y+scr_h - H;
//Make border's upper left corner visible //Make border's upper left corner visible
if (X<0) X = 0; if (X<scr_x) X = scr_x;
if (Y<0) Y = 0; if (Y<scr_y) Y = scr_y;
//Make client area's lower right corner visible //Make client area's lower right corner visible
if (Fl::w() < X+dx+ w->w()) X = Fl::w() - w->w() - dx; if (scr_x+scr_w < X+dx+ w->w()) X = scr_x+scr_w - w->w() - dx;
if (Fl::h() < Y+dy+ w->h()) Y = Fl::h() - w->h() - dy; if (scr_y+scr_h < Y+dy+ w->h()) Y = scr_y+scr_h - w->h() - dy;
//Make client area's upper left corner visible //Make client area's upper left corner visible
if (X+xoff < 0) X = -xoff; if (X+xoff < scr_x) X = scr_x-xoff;
if (Y+yoff < 0) Y = -yoff; if (Y+yoff < scr_y) Y = scr_y-yoff;
//Return the client area's top left corner in (X,Y) //Return the client area's top left corner in (X,Y)
X+=xoff; X+=xoff;
Y+=yoff; Y+=yoff;
+13 -10
View File
@@ -1042,13 +1042,16 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
// center windows in case window manager does not do anything: // center windows in case window manager does not do anything:
#ifdef FL_CENTER_WINDOWS #ifdef FL_CENTER_WINDOWS
if (!(win->flags() & Fl_Window::FL_FORCE_POSITION)) { if (!(win->flags() & Fl_Window::FL_FORCE_POSITION)) {
win->x(X = (Fl::w()-W)/2); win->x(X = scr_x+(scr_w-W)/2);
win->y(Y = (Fl::h()-H)/2); win->y(Y = scr_y+(scr_h-H)/2);
} }
#endif // FL_CENTER_WINDOWS #endif // FL_CENTER_WINDOWS
// force the window to be on-screen. Usually the X window manager // force the window to be on-screen. Usually the X window manager
// does this, but a few don't, so we do it here for consistency: // does this, but a few don't, so we do it here for consistency:
int scr_x, scr_y, scr_w, scr_h;
Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
if (win->border()) { if (win->border()) {
// ensure border is on screen: // ensure border is on screen:
// (assumme extremely minimal dimensions for this border) // (assumme extremely minimal dimensions for this border)
@@ -1056,16 +1059,16 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
const int left = 1; const int left = 1;
const int right = 1; const int right = 1;
const int bottom = 1; const int bottom = 1;
if (X+W+right > Fl::w()) X = Fl::w()-right-W; if (X+W+right > scr_x+scr_w) X = scr_x+scr_w-right-W;
if (X-left < 0) X = left; if (X-left < scr_x) X = scr_x+left;
if (Y+H+bottom > Fl::h()) Y = Fl::h()-bottom-H; if (Y+H+bottom > scr_y+scr_h) Y = scr_y+scr_h-bottom-H;
if (Y-top < 0) Y = top; if (Y-top < scr_y) Y = scr_y+top;
} }
// now insure contents are on-screen (more important than border): // now insure contents are on-screen (more important than border):
if (X+W > Fl::w()) X = Fl::w()-W; if (X+W > scr_x+scr_w) X = scr_x+scr_w-W;
if (X < 0) X = 0; if (X < scr_x) X = scr_x;
if (Y+H > Fl::h()) Y = Fl::h()-H; if (Y+H > scr_y+scr_h) Y = scr_y+scr_h-H;
if (Y < 0) Y = 0; if (Y < scr_y) Y = scr_y;
} }
ulong root = win->parent() ? ulong root = win->parent() ?
+6 -2
View File
@@ -116,8 +116,12 @@ int ColorMenu::handle(int e) {
int by = (c/8)*BOXSIZE+BORDER; int by = (c/8)*BOXSIZE+BORDER;
int px = x(); int px = x();
int py = y(); int py = y();
if (px+bx+BOXSIZE+BORDER >= Fl::w()) px = Fl::w()-bx-BOXSIZE-BORDER; int scr_x, scr_y, scr_w, scr_h;
if (py+by+BOXSIZE+BORDER >= Fl::h()) py = Fl::h()-by-BOXSIZE-BORDER; Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
if (px < scr_x) px = scr_x;
if (px+bx+BOXSIZE+BORDER >= scr_x+scr_w) px = scr_x+scr_w-bx-BOXSIZE-BORDER;
if (py < scr_y) py = scr_y;
if (py+by+BOXSIZE+BORDER >= scr_y+scr_h) py = scr_y+scr_h-by-BOXSIZE-BORDER;
if (px+bx < BORDER) px = BORDER-bx; if (px+bx < BORDER) px = BORDER-bx;
if (py+by < BORDER) py = BORDER-by; if (py+by < BORDER) py = BORDER-by;
position(px,py); position(px,py);
+5 -2
View File
@@ -95,8 +95,11 @@ void fl_show_form(Fl_Window *f,int place,int b,const char *n) {
if (place & FL_PLACE_MOUSE) f->hotspot(f); if (place & FL_PLACE_MOUSE) f->hotspot(f);
if (place & FL_PLACE_CENTER) if (place & FL_PLACE_CENTER) {
f->position((Fl::w()-f->w())/2, (Fl::h()-f->h())/2); int scr_x, scr_y, scr_w, scr_h;
Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
f->position(scr_x+(scr_w-f->w())/2, scr_y+(scr_h-f->h())/2);
}
if (place & FL_PLACE_FULLSCREEN) if (place & FL_PLACE_FULLSCREEN)
f->fullscreen(); f->fullscreen();
+40
View File
@@ -56,6 +56,23 @@ static void screen_init() {
EnumDisplayMonitors(0,0,screen_cb,0); EnumDisplayMonitors(0,0,screen_cb,0);
} }
} }
#elif defined(__APPLE__)
XRectangle screens[16];
static void screen_init() {
GDHandle gd;
for (gd = GetDeviceList(), num_screens = 0; gd; gd = GetNextDevice(gd)) {
GDPtr gp = *gd;
screens[num_screens].x = gp->gdRect.left;
screens[num_screens].y = gp->gdRect.top;
screens[num_screens].width = gp->gdRect.right - gp->gdRect.left;
screens[num_screens].height = gp->gdRect.bottom - gp->gdRect.top;
num_screens ++;
if (num_screens >= 16) break;
}
}
#elif defined(HAVE_XINERAMA) #elif defined(HAVE_XINERAMA)
# include <X11/extensions/Xinerama.h> # include <X11/extensions/Xinerama.h>
@@ -103,6 +120,22 @@ void Fl::screen_xywh(int &x, int &y, int &w, int &h, int mx, int my) {
} }
} }
#elif defined(__APPLE__) #elif defined(__APPLE__)
if (num_screens > 0) {
int i;
for (i = 0; i < num_screens; i ++) {
if (mx >= screens[i].x &&
mx < (screens[i].x + screens[i].width) &&
my >= screens[i].y &&
my < (screens[i].y + screens[i].height)) {
x = screens[i].x;
y = screens[i].y;
w = screens[i].width;
h = screens[i].height;
return;
}
}
}
#elif defined(HAVE_XINERAMA) #elif defined(HAVE_XINERAMA)
if (num_screens > 0) { if (num_screens > 0) {
int i; int i;
@@ -141,6 +174,13 @@ void Fl::screen_xywh(int &x, int &y, int &w, int &h, int n) {
return; return;
} }
#elif defined(__APPLE__) #elif defined(__APPLE__)
if (num_screens > 0 && n >= 0 && n < num_screens) {
x = screens[n].x;
y = screens[n].y;
w = screens[n].width;
h = screens[n].height;
return;
}
#elif defined(HAVE_XINERAMA) #elif defined(HAVE_XINERAMA)
if (num_screens > 0 && n >= 0 && n < num_screens) { if (num_screens > 0 && n >= 0 && n < num_screens) {
x = screens[n].x_org; x = screens[n].x_org;