Re: [AD] RFC - Linux WM Fullscreen Patch |
[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]
Looked at SDL closer - it behaves differently than I was told. It
doesn't scale at all, it uses the window manager to go fullscreen
and then xrandr/xvidmode to change the mode. Better for us, I did
the same and the patch is a ton simpler now. I'd like to propose changing ALLEGRO_FULLSCREEN_WINDOW so that it implies ALLEGRO_FULLSCREEN as well. That'll require a few changed checks here and there but not as bad as making ALLEGRO_FULLSCREEN separate from ALLEGRO_FULLSCREEN_WINDOW and ALLEGRO_FULLSCREEN_VIRTUAL. IMO it should have been that way from the start, as a modifier. I still didn't figure out why alt-tab doesn't work but this is by far better than ALLEGRO_FULLSCREEN or ALLEGRO_FULLSCREEN_WINDOW where it doesn't work either. Will try and figure it out eventually. Attached the patch, if there are no legitimate objections I'll apply it soon. I'll add documentation as well. On 14-08-07 10:55 AM, Trent Gamblin
wrote:
Attached xwmfullscreen.c. With this version KDE, Unity and XFCE all work except for alt-tabbing. Need to find out what SDL does to allow that. |
diff --git a/cmake/FileList.cmake b/cmake/FileList.cmake index ede9c57..007dddd 100644 --- a/cmake/FileList.cmake +++ b/cmake/FileList.cmake @@ -114,6 +114,7 @@ set(ALLEGRO_SRC_X_FILES src/x/xrandr.c src/x/xsystem.c src/x/xwindow.c + src/x/xwmfullscreen.c src/linux/lhaptic.c src/linux/ljoynu.c ) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b4ad048..7b5047f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -114,7 +114,7 @@ example(ex_blend_bench ${IMAGE} ${PRIM} ${DATA_IMAGES}) example(ex_blend_test ${PRIM}) example(ex_blit ${FONT} ${IMAGE} ${COLOR} ${DATA_IMAGES}) example(ex_clip ${FONT} ${COLOR}) -example(ex_color ex_color.cpp ${NIHGUI} ${TTF} ${COLOR} DATA ${DATA_TTF}) +example(ex_color ex_color.cpp ${NIHGUI} ${TTF} ${COLOR} ${IMAGE} DATA ${DATA_TTF}) example(ex_convert CONSOLE ${IMAGE}) example(ex_depth_mask ${IMAGE} ${TTF} ${DATA_IMAGES} ${DATA_TTF}) example(ex_disable_screensaver ${FONT}) @@ -131,7 +131,7 @@ example(ex_fs_window ${IMAGE} ${PRIM} ${FONT} ${DATA_IMAGES}) example(ex_icon ${IMAGE} ${DATA_IMAGES}) example(ex_icon2 ${IMAGE} ${DATA_IMAGES}) example(ex_haptic ${PRIM}) -example(ex_haptic2 ex_haptic2.cpp ${NIHGUI} ${TTF} DATA ${DATA_TTF}) +example(ex_haptic2 ex_haptic2.cpp ${NIHGUI} ${TTF} ${IMAGE} DATA ${DATA_TTF}) example(ex_joystick_events ${PRIM} ${FONT}) example(ex_joystick_hotplugging ${PRIM}) example(ex_keyboard_events) @@ -194,7 +194,7 @@ example(ex_font ${FONT} ${IMAGE} ${DATA_IMAGES}) example(ex_font_justify ex_font_justify.cpp ${NIHGUI} ${IMAGE} ${TTF} ${DATA_IMAGES} ${DATA_TTF}) example(ex_logo ${FONT} ${TTF} ${IMAGE} ${PRIM} DATA ${DATA_TTF}) example(ex_projection ${TTF} ${IMAGE} ${DATA_IMAGES} ${DATA_TTF}) -example(ex_ttf ${TTF} ${PRIM} DATA ${DATA_TTF} ex_ttf.ini) +example(ex_ttf ${TTF} ${PRIM} ${IMAGE} DATA ${DATA_TTF} ex_ttf.ini) example(ex_acodec CONSOLE ${AUDIO} ${ACODEC}) example(ex_acodec_multi CONSOLE ${AUDIO} ${ACODEC}) diff --git a/include/allegro5/display.h b/include/allegro5/display.h index 1d729cd..e463f7e 100644 --- a/include/allegro5/display.h +++ b/include/allegro5/display.h @@ -24,7 +24,8 @@ enum { ALLEGRO_FULLSCREEN_WINDOW = 1 << 9, ALLEGRO_MINIMIZED = 1 << 10, ALLEGRO_PROGRAMMABLE_PIPELINE = 1 << 11, - ALLEGRO_GTK_TOPLEVEL_INTERNAL = 1 << 12 + ALLEGRO_GTK_TOPLEVEL_INTERNAL = 1 << 12, + ALLEGRO_FULLSCREEN_VIRTUAL = 1 << 13 }; /* Possible parameters for al_set_display_option. diff --git a/include/allegro5/internal/aintern_xdisplay.h b/include/allegro5/internal/aintern_xdisplay.h index a8e616d..608b195 100644 --- a/include/allegro5/internal/aintern_xdisplay.h +++ b/include/allegro5/internal/aintern_xdisplay.h @@ -92,6 +92,8 @@ struct ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE bool _al_xwin_set_gtk_display_overridable_interface(uint32_t check_version, const ALLEGRO_XWIN_DISPLAY_OVERRIDABLE_INTERFACE *vt); +bool x_set_fullscreen_via_net_wm(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, bool fullscreen); + #endif /* !ALLEGRO_RASPBERRYPI */ #endif diff --git a/src/display.c b/src/display.c index 3becdf0..0c1b68a 100644 --- a/src/display.c +++ b/src/display.c @@ -51,6 +51,12 @@ ALLEGRO_DISPLAY *al_create_display(int w, int h) return NULL; } + flags = al_get_new_display_flags(); + if (flags & ALLEGRO_FULLSCREEN_VIRTUAL) { + flags |= ALLEGRO_FULLSCREEN; + al_set_new_display_flags(flags); + } + display = driver->create_display(w, h); if (!display) { ALLEGRO_ERROR("Failed to create display (NULL)\n"); diff --git a/src/x/xfullscreen.c b/src/x/xfullscreen.c index 0651e46..ea55e1d 100644 --- a/src/x/xfullscreen.c +++ b/src/x/xfullscreen.c @@ -364,7 +364,12 @@ static bool xfvm_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int w { int mode_idx = -1; int adapter = _al_xglx_get_adapter(s, d, false); - + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d; + + if (display->flags & ALLEGRO_FULLSCREEN_VIRTUAL) { + x_set_fullscreen_via_net_wm(s, d, true); + } + #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA /* TwinView workarounds, nothing to do here, since we can't really change or restore modes */ if (s->xinerama_available && s->xinerama_screen_count != s->xfvm_screen_count) { diff --git a/src/x/xrandr.c b/src/x/xrandr.c index 36f3857..222885c 100644 --- a/src/x/xrandr.c +++ b/src/x/xrandr.c @@ -503,7 +503,12 @@ static bool xrandr_set_mode(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, int { int adapter = _al_xglx_get_adapter(s, d, false); int xscreen = _al_xglx_get_xscreen(s, adapter); - + ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d; + + if (display->flags & ALLEGRO_FULLSCREEN_VIRTUAL) { + x_set_fullscreen_via_net_wm(s, d, true); + } + xrandr_screen *screen = _al_vector_ref(&s->xrandr_screens, xscreen); xrandr_crtc *crtc = xrandr_map_to_crtc(s, xscreen, adapter); diff --git a/src/x/xwmfullscreen.c b/src/x/xwmfullscreen.c index a497b87..24261c6 100644 --- a/src/x/xwmfullscreen.c +++ b/src/x/xwmfullscreen.c @@ -14,48 +14,9 @@ ALLEGRO_DEBUG_CHANNEL("display") #define _NET_WM_STATE_ADD 1l #define _NET_WM_STATE_TOGGLE 2l -/* The following code uses the window manager to set a fullscreen mode when supported */ +#define GET_ATOM(X) XInternAtom(display, #X, False) -bool x_set_fullscreen_via_net_wm(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d) -{ - Display *display = s->x11display; -#define GET_ATOM(X) X = XInternAtom(display, #X, False) - Atom _NET_WM_STATE = GET_ATOM(_NET_WM_STATE); - Atom _NET_WM_STATE_FULLSCREEN = GET_ATOM(_NET_WM_STATE_FULLSCREEN); -#undef GET_ATOM - - XEvent e; - - /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we - can be resized to the fullscreen resolution (or reset so we're not resizable again) */ - XSizeHints *sizehints = XAllocSizeHints(); - long flags = 0; - - XGetWMNormalHints(display, d->window, sizehints, &flags); - /* set the resize flags on */ - /* we are going fullscreen so turn the flags off */ - sizehints->flags &= ~(PMinSize | PMaxSize); - XSetWMNormalHints(display, d->window, sizehints); - XFree(sizehints); - - memset(&e, 0, sizeof(e)); - e.xany.type = ClientMessage; - e.xclient.message_type = _NET_WM_STATE; - e.xclient.format = 32; - e.xclient.window = d->window; - e.xclient.data.l[0] =_NET_WM_STATE_ADD; - e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; - e.xclient.data.l[3] = 0l; - - XSendEvent(display, RootWindow(display, DefaultScreen(display)), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); - - XFlush(display); - - return true; -} - -bool x_have_net_supporting_wm(Display *display) +static bool have_net_supporting_wm(Display *display) { Atom _NET_SUPPORTING_WM_CHECK; int status, real_format; @@ -98,3 +59,66 @@ bool x_have_net_supporting_wm(Display *display) return true; } +bool x_set_fullscreen_via_net_wm(ALLEGRO_SYSTEM_XGLX *s, ALLEGRO_DISPLAY_XGLX *d, bool fullscreen) +{ + Display *display = s->x11display; + Atom _NET_WM_STATE = GET_ATOM(_NET_WM_STATE); + Atom _NET_WM_STATE_FULLSCREEN = GET_ATOM(_NET_WM_STATE_FULLSCREEN); + + if (!have_net_supporting_wm(s->x11display)) { + return false; + } + + if (d->is_mapped) { + XEvent e; + + XSizeHints *sizehints = XAllocSizeHints(); + long flags = 0; + XGetWMNormalHints(display, d->window, sizehints, &flags); + /* set the resize flags on */ + if (fullscreen) { + /* we are going fullscreen so turn the flags off */ + sizehints->flags &= ~(PMinSize | PMaxSize); + } + else { + /* Reset the min/max width height to make the window non-resizable again */ + sizehints->flags |= PMinSize | PMaxSize; + sizehints->min_width = sizehints->max_width = d->display.w; + sizehints->min_height = sizehints->max_height = d->display.h; + } + XSetWMNormalHints(display, d->window, sizehints); + XFree(sizehints); + + memset(&e, 0, sizeof(e)); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = d->window; + e.xclient.data.l[0] = + fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; + e.xclient.data.l[3] = 0l; + + XSendEvent(display, RootWindow(display, DefaultScreen(display)), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + } + else { + Atom _NET_WM_STATE_MAXIMIZED_VERT = GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); + Atom _NET_WM_STATE_MAXIMIZED_HORZ = GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); + Atom _NET_WM_STATE_FOCUSED = GET_ATOM(_NET_WM_STATE_FOCUSED); + + Atom atoms[4]; + + atoms[0] = _NET_WM_STATE_MAXIMIZED_VERT; + atoms[1] = _NET_WM_STATE_MAXIMIZED_HORZ; + atoms[2] = _NET_WM_STATE_FULLSCREEN; + atoms[3] = _NET_WM_STATE_FOCUSED; + + XChangeProperty(display, d->window, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, 4); + } + + XFlush(display); + + return true; +} +
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |