summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-06-11 09:10:53 +0000
committerPierre Ossman <ossman@cendio.se>2014-06-11 09:10:53 +0000
commit0cfc2554c695bd472ce9e579ddcf1240f4fa155a (patch)
tree0b3723e49f86b076a19f110a4923b3c72389c576 /src
parentf27bde8316b28db2fc3214ce97fd4278e2d9efec (diff)
Support for full screen over multiple monitors.
The API follows that of EWMH, which gives you a good control over which monitors to use. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10189 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Window_fullscreen.cxx21
-rw-r--r--src/Fl_cocoa.mm29
-rw-r--r--src/Fl_win32.cxx36
-rw-r--r--src/Fl_x.cxx76
4 files changed, 143 insertions, 19 deletions
diff --git a/src/Fl_Window_fullscreen.cxx b/src/Fl_Window_fullscreen.cxx
index 7a8ce4631..6b0d400e4 100644
--- a/src/Fl_Window_fullscreen.cxx
+++ b/src/Fl_Window_fullscreen.cxx
@@ -36,6 +36,10 @@ int Fl_Window::no_fullscreen_x = 0;
int Fl_Window::no_fullscreen_y = 0;
int Fl_Window::no_fullscreen_w = 0;
int Fl_Window::no_fullscreen_h = 0;
+int Fl_Window::fullscreen_screen_top = -1;
+int Fl_Window::fullscreen_screen_bottom = -1;
+int Fl_Window::fullscreen_screen_left = -1;
+int Fl_Window::fullscreen_screen_right = -1;
#endif
void Fl_Window::border(int b) {
@@ -95,6 +99,23 @@ void Fl_Window::fullscreen_off() {
fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h);
}
+void Fl_Window::fullscreen_screens(int top, int bottom, int left, int right) {
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ fullscreen_screen_top = -1;
+ fullscreen_screen_bottom = -1;
+ fullscreen_screen_left = -1;
+ fullscreen_screen_right = -1;
+ } else {
+ fullscreen_screen_top = top;
+ fullscreen_screen_bottom = bottom;
+ fullscreen_screen_left = left;
+ fullscreen_screen_right = right;
+ }
+
+ if (shown() && fullscreen_active())
+ fullscreen_x();
+}
+
//
// End of "$Id$".
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index b341acd20..a60b61a46 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -2394,9 +2394,32 @@ void Fl_X::make(Fl_Window* w)
NSRect crect;
if (w->fullscreen_active()) {
- int sx, sy, sw, sh;
- Fl::screen_xywh(sx, sy, sw, sh, w->x(), w->y(), w->w(), w->h());
- w->resize(sx, sy, sw, sh);
+ int top, bottom, left, right;
+ int sx, sy, sw, sh, X, Y, W, H;
+
+ top = w->fullscreen_screen_top;
+ bottom = w->fullscreen_screen_bottom;
+ left = w->fullscreen_screen_left;
+ right = w->fullscreen_screen_right;
+
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ top = Fl::screen_num(w->x(), w->y(), w->w(), w->h());
+ bottom = top;
+ left = top;
+ right = top;
+ }
+
+ Fl::screen_xywh(sx, sy, sw, sh, top);
+ Y = sy;
+ Fl::screen_xywh(sx, sy, sw, sh, bottom);
+ H = sy + sh - Y;
+ Fl::screen_xywh(sx, sy, sw, sh, left);
+ X = sx;
+ Fl::screen_xywh(sx, sy, sw, sh, right);
+ W = sx + sw - X;
+
+ w->resize(X, Y, W, H);
+
winstyle = NSBorderlessWindowMask;
winlevel = NSStatusWindowLevel;
}
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index ba8915b10..fceae16f1 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -1483,7 +1483,6 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
Y+=yoff;
if (w->fullscreen_active()) {
- X = Y = 0;
bx = by = bt = 0;
}
@@ -1537,19 +1536,42 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
}
}
-static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) {
+void Fl_X::make_fullscreen(int X, int Y, int W, int H) {
+ int top, bottom, left, right;
int sx, sy, sw, sh;
- Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H);
+
+ top = w->fullscreen_screen_top;
+ bottom = w->fullscreen_screen_bottom;
+ left = w->fullscreen_screen_left;
+ right = w->fullscreen_screen_right;
+
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ top = Fl::screen_num(X, Y, W, H);
+ bottom = top;
+ left = top;
+ right = top;
+ }
+
+ Fl::screen_xywh(sx, sy, sw, sh, top);
+ Y = sy;
+ Fl::screen_xywh(sx, sy, sw, sh, bottom);
+ H = sy + sh - Y;
+ Fl::screen_xywh(sx, sy, sw, sh, left);
+ X = sx;
+ Fl::screen_xywh(sx, sy, sw, sh, right);
+ W = sx + sw - X;
+
DWORD flags = GetWindowLong(xid, GWL_STYLE);
flags = flags & ~(WS_THICKFRAME|WS_CAPTION);
SetWindowLong(xid, GWL_STYLE, flags);
+
// SWP_NOSENDCHANGING is so that we can override size limits
- SetWindowPos(xid, HWND_TOP, sx, sy, sw, sh, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
+ SetWindowPos(xid, HWND_TOP, X, Y, W, H, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
}
void Fl_Window::fullscreen_x() {
_set_fullscreen();
- make_fullscreen(this, fl_xid(this), x(), y(), w(), h());
+ i->make_fullscreen(x(), y(), w(), h());
Fl::handle(FL_FULLSCREEN, this);
}
@@ -1802,8 +1824,8 @@ Fl_X* Fl_X::make(Fl_Window* w) {
monitor the window was placed on. */
RECT rect;
GetWindowRect(x->xid, &rect);
- make_fullscreen(w, x->xid, rect.left, rect.top,
- rect.right - rect.left, rect.bottom - rect.top);
+ x->make_fullscreen(rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top);
}
x->next = Fl_X::first;
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index d86596a1d..bc5810b7c 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -345,6 +345,7 @@ Atom fl_NET_WM_ICON_NAME; // utf8 aware window icon name
Atom fl_NET_SUPPORTING_WM_CHECK;
Atom fl_NET_WM_STATE;
Atom fl_NET_WM_STATE_FULLSCREEN;
+Atom fl_NET_WM_FULLSCREEN_MONITORS;
Atom fl_NET_WORKAREA;
/*
@@ -654,6 +655,7 @@ void fl_open_display(Display* d) {
fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
fl_NET_WM_STATE = XInternAtom(d, "_NET_WM_STATE", 0);
fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
+ fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0);
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0);
if (sizeof(Atom) < 4)
@@ -2147,22 +2149,30 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
-static void send_wm_state_event(Window wnd, int add, Atom prop) {
+static void send_wm_event(Window wnd, Atom message,
+ unsigned long d0, unsigned long d1=0,
+ unsigned long d2=0, unsigned long d3=0,
+ unsigned long d4=0) {
XEvent e;
e.xany.type = ClientMessage;
e.xany.window = wnd;
- e.xclient.message_type = fl_NET_WM_STATE;
+ e.xclient.message_type = message;
e.xclient.format = 32;
- e.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
- e.xclient.data.l[1] = prop;
- e.xclient.data.l[2] = 0;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
+ e.xclient.data.l[0] = d0;
+ e.xclient.data.l[1] = d1;
+ e.xclient.data.l[2] = d2;
+ e.xclient.data.l[3] = d3;
+ e.xclient.data.l[4] = d4;
XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
0, SubstructureNotifyMask | SubstructureRedirectMask,
&e);
}
+static void send_wm_state_event(Window wnd, int add, Atom prop) {
+ send_wm_event(wnd, fl_NET_WM_STATE,
+ add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, prop);
+}
+
int Fl_X::ewmh_supported() {
static int result = -1;
@@ -2188,6 +2198,22 @@ int Fl_X::ewmh_supported() {
/* Change an existing window to fullscreen */
void Fl_Window::fullscreen_x() {
if (Fl_X::ewmh_supported()) {
+ int top, bottom, left, right;
+
+ top = fullscreen_screen_top;
+ bottom = fullscreen_screen_bottom;
+ left = fullscreen_screen_left;
+ right = fullscreen_screen_right;
+
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ top = Fl::screen_num(x(), y(), w(), h());
+ bottom = top;
+ left = top;
+ right = top;
+ }
+
+ send_wm_event(fl_xid(this), fl_NET_WM_FULLSCREEN_MONITORS,
+ top, bottom, left, right);
send_wm_state_event(fl_xid(this), 1, fl_NET_WM_STATE_FULLSCREEN);
} else {
_set_fullscreen();
@@ -2274,7 +2300,7 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
// 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, X, Y);
+ Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H);
if (win->border()) {
// ensure border is on screen:
@@ -2303,6 +2329,23 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
return;
}
+ // Compute which screen(s) we should be on if we want to go fullscreen
+ int fullscreen_top, fullscreen_bottom, fullscreen_left, fullscreen_right;
+
+ fullscreen_top = win->fullscreen_screen_top;
+ fullscreen_bottom = win->fullscreen_screen_bottom;
+ fullscreen_left = win->fullscreen_screen_left;
+ fullscreen_right = win->fullscreen_screen_right;
+
+ if ((fullscreen_top < 0) || (fullscreen_bottom < 0) ||
+ (fullscreen_left < 0) || (fullscreen_right < 0)) {
+ fullscreen_top = Fl::screen_num(X, Y, W, H);
+ fullscreen_bottom = fullscreen_top;
+ fullscreen_left = fullscreen_top;
+ fullscreen_right = fullscreen_top;
+ }
+
+
ulong root = win->parent() ?
fl_xid(win->window()) : RootWindow(fl_display, fl_screen);
@@ -2326,9 +2369,17 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
// border, and cannot grab without an existing window. Besides,
// there is no clear_override().
if (win->fullscreen_active() && !Fl_X::ewmh_supported()) {
+ int sx, sy, sw, sh;
attr.override_redirect = 1;
mask |= CWOverrideRedirect;
- Fl::screen_xywh(X, Y, W, H, X, Y, W, H);
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_left);
+ X = sx;
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_right);
+ W = sx + sw - X;
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_top);
+ Y = sy;
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_bottom);
+ H = sy + sh - Y;
}
if (fl_background_pixel >= 0) {
@@ -2393,6 +2444,13 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
// If asked for, create fullscreen
if (win->fullscreen_active() && Fl_X::ewmh_supported()) {
+ unsigned long data[4];
+ data[0] = fullscreen_top;
+ data[1] = fullscreen_bottom;
+ data[2] = fullscreen_left;
+ data[3] = fullscreen_right;
+ XChangeProperty (fl_display, xp->xid, fl_NET_WM_FULLSCREEN_MONITORS, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*) data, 4);
XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
}