mirror of
https://github.com/fltk/fltk.git
synced 2026-06-04 23:42:15 +08:00
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:
+7
-38
@@ -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)
|
||||
: Fl_Menu_Window(X, Y, Wp, Hp, 0)
|
||||
{
|
||||
int scr_right = Fl::x() + Fl::w();
|
||||
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
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
|
||||
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();
|
||||
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 (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);
|
||||
h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3);
|
||||
if (selected >= 0)
|
||||
@@ -344,24 +327,10 @@ void menuwindow::position(int X, int Y) {
|
||||
|
||||
// scroll so item i is visible on screen
|
||||
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;
|
||||
#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_y = gp->gdRect.top; scr_h = gp->gdRect.bottom - gp->gdRect.top + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
Fl::screen_xywh(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;
|
||||
|
||||
+7
-5
@@ -75,15 +75,17 @@ void Fl_TooltipBox::layout() {
|
||||
//ox += p->x();
|
||||
oy += p->y();
|
||||
}
|
||||
if (ox+ww > Fl::w()) ox = Fl::w() - ww;
|
||||
if (ox < 0) ox = 0;
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
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) {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
if (X==x()) x(X-1);
|
||||
#else
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
|
||||
|
||||
if (border()) {
|
||||
// Ensure border is on screen; these values are generic enough
|
||||
// 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 right = 4;
|
||||
const int bottom = 8;
|
||||
if (X+w()+right > Fl::w()-Fl::x()) X = Fl::w()-Fl::x()-right-w();
|
||||
if (X-left < Fl::x()) X = left;
|
||||
if (Y+h()+bottom > Fl::h()-Fl::y()) Y = Fl::h()-Fl::y()-bottom-h();
|
||||
if (Y-top < Fl::y()) Y = top;
|
||||
if (X+w()+right > scr_w-scr_x) X = scr_w-scr_x-right-w();
|
||||
if (X-left < scr_x) X = left;
|
||||
if (Y+h()+bottom > scr_h-scr_y) Y = scr_h-scr_y-bottom-h();
|
||||
if (Y-top < scr_y) Y = top;
|
||||
}
|
||||
// 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 < Fl::x()) X = Fl::x();
|
||||
if (Y+h() > Fl::h()-Fl::y()) Y = Fl::h()-Fl::y()-h();
|
||||
if (Y < Fl::y()) Y = Fl::y();
|
||||
if (X+w() > scr_w-scr_x) X = scr_w-scr_x-w();
|
||||
if (X < scr_x) X = scr_x;
|
||||
if (Y+h() > scr_h-scr_y) Y = scr_h-scr_y-h();
|
||||
if (Y < scr_y) Y = scr_y;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -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
|
||||
//Make border's lower right corner visible
|
||||
if (Fl::w() < X+W) X = Fl::w() - W;
|
||||
if (Fl::h() < Y+H) Y = Fl::h() - H;
|
||||
int scr_x, scr_y, scr_w, scr_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
|
||||
if (X<0) X = 0;
|
||||
if (Y<0) Y = 0;
|
||||
if (X<scr_x) X = scr_x;
|
||||
if (Y<scr_y) Y = scr_y;
|
||||
//Make client area's lower right corner visible
|
||||
if (Fl::w() < X+dx+ w->w()) X = Fl::w() - w->w() - dx;
|
||||
if (Fl::h() < Y+dy+ w->h()) Y = Fl::h() - w->h() - dy;
|
||||
if (scr_x+scr_w < X+dx+ w->w()) X = scr_x+scr_w - w->w() - dx;
|
||||
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
|
||||
if (X+xoff < 0) X = -xoff;
|
||||
if (Y+yoff < 0) Y = -yoff;
|
||||
if (X+xoff < scr_x) X = scr_x-xoff;
|
||||
if (Y+yoff < scr_y) Y = scr_y-yoff;
|
||||
//Return the client area's top left corner in (X,Y)
|
||||
X+=xoff;
|
||||
Y+=yoff;
|
||||
|
||||
+13
-10
@@ -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:
|
||||
#ifdef FL_CENTER_WINDOWS
|
||||
if (!(win->flags() & Fl_Window::FL_FORCE_POSITION)) {
|
||||
win->x(X = (Fl::w()-W)/2);
|
||||
win->y(Y = (Fl::h()-H)/2);
|
||||
win->x(X = scr_x+(scr_w-W)/2);
|
||||
win->y(Y = scr_y+(scr_h-H)/2);
|
||||
}
|
||||
#endif // FL_CENTER_WINDOWS
|
||||
|
||||
// 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:
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h);
|
||||
|
||||
if (win->border()) {
|
||||
// ensure border is on screen:
|
||||
// (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 right = 1;
|
||||
const int bottom = 1;
|
||||
if (X+W+right > Fl::w()) X = Fl::w()-right-W;
|
||||
if (X-left < 0) X = left;
|
||||
if (Y+H+bottom > Fl::h()) Y = Fl::h()-bottom-H;
|
||||
if (Y-top < 0) Y = top;
|
||||
if (X+W+right > scr_x+scr_w) X = scr_x+scr_w-right-W;
|
||||
if (X-left < scr_x) X = scr_x+left;
|
||||
if (Y+H+bottom > scr_y+scr_h) Y = scr_y+scr_h-bottom-H;
|
||||
if (Y-top < scr_y) Y = scr_y+top;
|
||||
}
|
||||
// now insure contents are on-screen (more important than border):
|
||||
if (X+W > Fl::w()) X = Fl::w()-W;
|
||||
if (X < 0) X = 0;
|
||||
if (Y+H > Fl::h()) Y = Fl::h()-H;
|
||||
if (Y < 0) Y = 0;
|
||||
if (X+W > scr_x+scr_w) X = scr_x+scr_w-W;
|
||||
if (X < scr_x) X = scr_x;
|
||||
if (Y+H > scr_y+scr_h) Y = scr_y+scr_h-H;
|
||||
if (Y < scr_y) Y = scr_y;
|
||||
}
|
||||
|
||||
ulong root = win->parent() ?
|
||||
|
||||
@@ -116,8 +116,12 @@ int ColorMenu::handle(int e) {
|
||||
int by = (c/8)*BOXSIZE+BORDER;
|
||||
int px = x();
|
||||
int py = y();
|
||||
if (px+bx+BOXSIZE+BORDER >= Fl::w()) px = Fl::w()-bx-BOXSIZE-BORDER;
|
||||
if (py+by+BOXSIZE+BORDER >= Fl::h()) py = Fl::h()-by-BOXSIZE-BORDER;
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
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 (py+by < BORDER) py = BORDER-by;
|
||||
position(px,py);
|
||||
|
||||
@@ -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_CENTER)
|
||||
f->position((Fl::w()-f->w())/2, (Fl::h()-f->h())/2);
|
||||
if (place & FL_PLACE_CENTER) {
|
||||
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)
|
||||
f->fullscreen();
|
||||
|
||||
@@ -56,6 +56,23 @@ static void screen_init() {
|
||||
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)
|
||||
# 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__)
|
||||
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)
|
||||
if (num_screens > 0) {
|
||||
int i;
|
||||
@@ -141,6 +174,13 @@ void Fl::screen_xywh(int &x, int &y, int &w, int &h, int n) {
|
||||
return;
|
||||
}
|
||||
#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)
|
||||
if (num_screens > 0 && n >= 0 && n < num_screens) {
|
||||
x = screens[n].x_org;
|
||||
|
||||
Reference in New Issue
Block a user