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 <Spectre/System/Log.h>
|
||||
#include <Spectre/Graphics/Image.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "XRandR.h"
|
||||
#include "X11WindowEventHandler.h"
|
||||
#include "Xlib.h"
|
||||
#include "wm_hints.h"
|
||||
|
|
@ -238,14 +240,75 @@ void X11Display::maximize()
|
|||
|
||||
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()
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
::XStoreName(Xlib::getDisplay(), m_win, caption.c_str());
|
||||
|
|
@ -329,10 +392,19 @@ void X11Display::processEvent(const ::XEvent& event)
|
|||
case FocusIn:
|
||||
Log::debug("X11: FocusIn");
|
||||
_priv::focused_display = this;
|
||||
|
||||
if (m_fullscreen_mode.rate > 0) {
|
||||
toggleFullscreen(true);
|
||||
}
|
||||
|
||||
break;
|
||||
case FocusOut:
|
||||
Log::debug("X11: FocusOut");
|
||||
_priv::focused_display = NULL;
|
||||
if (m_fullscreen_mode.rate > 0) {
|
||||
toggleFullscreen(false);
|
||||
minimize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <X11/Xos.h>
|
||||
#include <cstdint>
|
||||
#include <Platform/PlatformDisplay.h>
|
||||
#include "Xrandr.h"
|
||||
|
||||
namespace sp {
|
||||
|
||||
|
|
@ -62,6 +63,10 @@ protected :
|
|||
|
||||
void createHiddenCursor();
|
||||
|
||||
void toggleFullscreen(bool enabled);
|
||||
|
||||
void wm_fullscreen(bool enabled);
|
||||
|
||||
protected :
|
||||
|
||||
::Window m_win;
|
||||
|
|
@ -72,6 +77,10 @@ protected :
|
|||
::Cursor m_cur_last;
|
||||
|
||||
Vector2u m_size;
|
||||
|
||||
XRandR::VideoMode m_fullscreen_mode;
|
||||
|
||||
XRandR::VideoMode m_desktop_mode;
|
||||
};
|
||||
|
||||
} // namespace sp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue