source/Platform/Unix/X11Display.cpp: implement fullscreen somewhat correctly :)
This commit is contained in:
parent
186a6e0f14
commit
2cf035089b
2 changed files with 82 additions and 1 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <Spectre/System/Log.h>
|
#include <Spectre/System/Log.h>
|
||||||
#include <Spectre/Graphics/Image.h>
|
#include <Spectre/Graphics/Image.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include "XRandR.h"
|
||||||
#include "X11WindowEventHandler.h"
|
#include "X11WindowEventHandler.h"
|
||||||
#include "Xlib.h"
|
#include "Xlib.h"
|
||||||
#include "wm_hints.h"
|
#include "wm_hints.h"
|
||||||
|
|
@ -238,13 +240,74 @@ void X11Display::maximize()
|
||||||
|
|
||||||
void X11Display::enterFullscreen(DisplayMode mode)
|
void X11Display::enterFullscreen(DisplayMode mode)
|
||||||
{
|
{
|
||||||
|
if (!XRandR::FindMode(Xlib::getDisplay(), mode.width, mode.height, mode.bpp, &m_fullscreen_mode.size, &m_fullscreen_mode.rate)) {
|
||||||
|
Log::warn("X11: Failed to find a mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFullscreen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X11Display::toggleFullscreen(bool enable)
|
||||||
|
{
|
||||||
|
::Display* disp = Xlib::getDisplay();
|
||||||
|
::Window root;
|
||||||
|
::XRRScreenConfiguration *conf;
|
||||||
|
XRandR::VideoMode *mode = &m_desktop_mode;
|
||||||
|
|
||||||
|
root = RootWindow(disp, 0);
|
||||||
|
conf = XRRGetScreenInfo(disp, root);
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
if (m_desktop_mode.rate < 1) {
|
||||||
|
Rotation r;
|
||||||
|
m_desktop_mode.rate = XRRConfigCurrentRate(conf);
|
||||||
|
m_desktop_mode.size = XRRConfigCurrentConfiguration(conf, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = &m_fullscreen_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
wm_fullscreen(enable);
|
||||||
|
XRRSetScreenConfigAndRate(disp, conf, root, mode->size, RR_Rotate_0, mode->rate, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Display::exitFullscreen()
|
void X11Display::exitFullscreen()
|
||||||
{
|
{
|
||||||
|
if (m_fullscreen_mode.rate > 0) {
|
||||||
|
toggleFullscreen(false);
|
||||||
|
m_fullscreen_mode.rate = 0;
|
||||||
|
m_fullscreen_mode.size = 0;
|
||||||
|
m_desktop_mode.rate = 0;
|
||||||
|
m_desktop_mode.size = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
|
||||||
|
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
||||||
|
|
||||||
|
void X11Display::wm_fullscreen(bool enabled) {
|
||||||
|
|
||||||
|
::Display* disp = sp::Xlib::getDisplay();
|
||||||
|
|
||||||
|
XEvent xev;
|
||||||
|
Atom wm_state = sp::Xlib::getAtom("_NET_WM_STATE", False);
|
||||||
|
Atom wm_fs = sp::Xlib::getAtom("_NET_WM_STATE_FULLSCREEN", False);
|
||||||
|
|
||||||
|
memset(&xev, 0, sizeof(xev));
|
||||||
|
xev.type = ClientMessage;
|
||||||
|
xev.xclient.window = m_win;
|
||||||
|
xev.xclient.message_type = wm_state;
|
||||||
|
xev.xclient.format = 32;
|
||||||
|
xev.xclient.data.l[0] = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
||||||
|
xev.xclient.data.l[1] = wm_fs;
|
||||||
|
xev.xclient.data.l[2] = 0;
|
||||||
|
|
||||||
|
::XSendEvent(disp, ::XDefaultRootWindow(disp), False,
|
||||||
|
SubstructureRedirectMask | SubstructureNotifyMask,
|
||||||
|
&xev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void X11Display::setCaption(const std::string& caption)
|
void X11Display::setCaption(const std::string& caption)
|
||||||
{
|
{
|
||||||
|
|
@ -329,10 +392,19 @@ void X11Display::processEvent(const ::XEvent& event)
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
Log::debug("X11: FocusIn");
|
Log::debug("X11: FocusIn");
|
||||||
_priv::focused_display = this;
|
_priv::focused_display = this;
|
||||||
|
|
||||||
|
if (m_fullscreen_mode.rate > 0) {
|
||||||
|
toggleFullscreen(true);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
Log::debug("X11: FocusOut");
|
Log::debug("X11: FocusOut");
|
||||||
_priv::focused_display = NULL;
|
_priv::focused_display = NULL;
|
||||||
|
if (m_fullscreen_mode.rate > 0) {
|
||||||
|
toggleFullscreen(false);
|
||||||
|
minimize();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <X11/Xos.h>
|
#include <X11/Xos.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <Platform/PlatformDisplay.h>
|
#include <Platform/PlatformDisplay.h>
|
||||||
|
#include "Xrandr.h"
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
|
|
@ -62,6 +63,10 @@ protected :
|
||||||
|
|
||||||
void createHiddenCursor();
|
void createHiddenCursor();
|
||||||
|
|
||||||
|
void toggleFullscreen(bool enabled);
|
||||||
|
|
||||||
|
void wm_fullscreen(bool enabled);
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
::Window m_win;
|
::Window m_win;
|
||||||
|
|
@ -72,6 +77,10 @@ protected :
|
||||||
::Cursor m_cur_last;
|
::Cursor m_cur_last;
|
||||||
|
|
||||||
Vector2u m_size;
|
Vector2u m_size;
|
||||||
|
|
||||||
|
XRandR::VideoMode m_fullscreen_mode;
|
||||||
|
|
||||||
|
XRandR::VideoMode m_desktop_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue