mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
twice toggle maximizes for fullscreen.
This commit is contained in:
parent
3ef4c5ce0f
commit
47a3f6d6fb
@ -23,6 +23,9 @@ void XEventLoop(char *name) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save last size id for fullscreen bug fix
|
||||||
|
SizeID last_size_id;
|
||||||
|
|
||||||
Atom WM_WINDOW_ROLE = XInternAtom(display, "WM_WINDOW_ROLE", 1);
|
Atom WM_WINDOW_ROLE = XInternAtom(display, "WM_WINDOW_ROLE", 1);
|
||||||
Atom XA_CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0);
|
Atom XA_CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0);
|
||||||
XFixesSelectSelectionInput(display, root, XA_CLIPBOARD, XFixesSetSelectionOwnerNotifyMask);
|
XFixesSelectSelectionInput(display, root, XA_CLIPBOARD, XFixesSetSelectionOwnerNotifyMask);
|
||||||
@ -75,27 +78,61 @@ void XEventLoop(char *name) {
|
|||||||
goXEventUnmapNotify(window);
|
goXEventUnmapNotify(window);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientMessage
|
||||||
|
if (event.type == ClientMessage) {
|
||||||
|
Window window = event.xclient.window;
|
||||||
|
|
||||||
|
// check for window manager state change
|
||||||
|
if (event.xclient.message_type == XInternAtom(display, "_NET_WM_STATE", 0)) {
|
||||||
|
// see documentation in XWindowManagerStateEvent
|
||||||
|
Atom action = event.xclient.data.l[0];
|
||||||
|
Atom first = event.xclient.data.l[1];
|
||||||
|
Atom second = event.xclient.data.l[2];
|
||||||
|
|
||||||
|
// check if user is entering or exiting fullscreen
|
||||||
|
if (first == XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0)) {
|
||||||
|
// get current size id
|
||||||
|
Rotation current_rotation;
|
||||||
|
XRRScreenConfiguration *conf = XRRGetScreenInfo(display, root);
|
||||||
|
SizeID current_size_id = XRRConfigCurrentConfiguration(conf, ¤t_rotation);
|
||||||
|
|
||||||
|
// window just went fullscreen
|
||||||
|
if (action == 1) {
|
||||||
|
// save current size id
|
||||||
|
last_size_id = current_size_id;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// window just exited fullscreen
|
||||||
|
if (action == 0) {
|
||||||
|
// if size id changed, that means user changed resolution while in fullscreen
|
||||||
|
// there is a bug in some window managers that causes the window to not resize
|
||||||
|
// if it was previously maximized, so we need to unmaximize it and maximize it again
|
||||||
|
if (current_size_id != last_size_id) {
|
||||||
|
// toggle maximized state twice
|
||||||
|
XWindowManagerStateEvent(display, window, 2,
|
||||||
|
XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", 0),
|
||||||
|
XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", 0));
|
||||||
|
XWindowManagerStateEvent(display, window, 2,
|
||||||
|
XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", 0),
|
||||||
|
XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XCloseDisplay(display);
|
XCloseDisplay(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFileChooserHide(Display *display, Window window) {
|
static void XWindowManagerStateEvent(Display *display, Window window, ulong action, ulong first, ulong second) {
|
||||||
Window root = RootWindow(display, 0);
|
Window root = DefaultRootWindow(display);
|
||||||
|
|
||||||
// The WM_TRANSIENT_FOR property is defined by the [ICCCM] for managed windows.
|
|
||||||
// This specification extends the use of the property to override-redirect windows.
|
|
||||||
// If an override-redirect is a pop-up on behalf of another window, then the Client
|
|
||||||
// SHOULD set WM_TRANSIENT_FOR on the override-redirect to this other window.
|
|
||||||
//
|
|
||||||
// As an example, a Client should set WM_TRANSIENT_FOR on dropdown menus to the
|
|
||||||
// toplevel application window that contains the menubar.
|
|
||||||
|
|
||||||
// Remove WM_TRANSIENT_FOR
|
|
||||||
Atom WM_TRANSIENT_FOR = XInternAtom(display, "WM_TRANSIENT_FOR", 0);
|
|
||||||
XDeleteProperty(display, window, WM_TRANSIENT_FOR);
|
|
||||||
|
|
||||||
// Add _NET_WM_STATE_BELOW
|
|
||||||
XClientMessageEvent clientMessageEvent;
|
XClientMessageEvent clientMessageEvent;
|
||||||
memset(&clientMessageEvent, 0, sizeof(clientMessageEvent));
|
memset(&clientMessageEvent, 0, sizeof(clientMessageEvent));
|
||||||
|
|
||||||
@ -115,9 +152,29 @@ void XFileChooserHide(Display *display, Window window) {
|
|||||||
clientMessageEvent.window = window;
|
clientMessageEvent.window = window;
|
||||||
clientMessageEvent.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
|
clientMessageEvent.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
|
||||||
clientMessageEvent.format = 32;
|
clientMessageEvent.format = 32;
|
||||||
clientMessageEvent.data.l[0] = 1;
|
clientMessageEvent.data.l[0] = action;
|
||||||
clientMessageEvent.data.l[1] = XInternAtom(display, "_NET_WM_STATE_BELOW", 0);
|
clientMessageEvent.data.l[1] = first;
|
||||||
|
clientMessageEvent.data.l[2] = second;
|
||||||
clientMessageEvent.data.l[3] = 1;
|
clientMessageEvent.data.l[3] = 1;
|
||||||
|
|
||||||
XSendEvent(display, root, 0, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&clientMessageEvent);
|
XSendEvent(display, root, 0, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&clientMessageEvent);
|
||||||
|
XFlush(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFileChooserHide(Display *display, Window window) {
|
||||||
|
// The WM_TRANSIENT_FOR property is defined by the [ICCCM] for managed windows.
|
||||||
|
// This specification extends the use of the property to override-redirect windows.
|
||||||
|
// If an override-redirect is a pop-up on behalf of another window, then the Client
|
||||||
|
// SHOULD set WM_TRANSIENT_FOR on the override-redirect to this other window.
|
||||||
|
//
|
||||||
|
// As an example, a Client should set WM_TRANSIENT_FOR on dropdown menus to the
|
||||||
|
// toplevel application window that contains the menubar.
|
||||||
|
|
||||||
|
// Remove WM_TRANSIENT_FOR
|
||||||
|
Atom WM_TRANSIENT_FOR = XInternAtom(display, "WM_TRANSIENT_FOR", 0);
|
||||||
|
XDeleteProperty(display, window, WM_TRANSIENT_FOR);
|
||||||
|
|
||||||
|
// Add _NET_WM_STATE_BELOW
|
||||||
|
XWindowManagerStateEvent(display, window, 1, // set property
|
||||||
|
XInternAtom(display, "_NET_WM_STATE_BELOW", 0), 0);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -17,4 +18,5 @@ extern int goXEventActive();
|
|||||||
static int XEventError(Display *display, XErrorEvent *event);
|
static int XEventError(Display *display, XErrorEvent *event);
|
||||||
void XEventLoop(char *display);
|
void XEventLoop(char *display);
|
||||||
|
|
||||||
|
static void XWindowManagerStateEvent(Display *display, Window window, ulong action, ulong first, ulong second);
|
||||||
void XFileChooserHide(Display *display, Window window);
|
void XFileChooserHide(Display *display, Window window);
|
||||||
|
Loading…
Reference in New Issue
Block a user