app: [X11] honour _NET_WM_STATE protocol

The _NET_WM_STATE protocol description[0] states that to change the
window mode for an X11,

"To change the state of a mapped window, a Client MUST send a
_NET_WM_STATE client message to the root window."

and that the window manager in turn

"The Window Manager MUST keep this property updated to reflect the
current state of the window."

However, our X11 implementation did both: send the message _and_ set or
deleted the property.

This change makes it so only the message is sent. It also replaces
toggling the property by setting or clearing, to ensure our mode and the
window manager's mode never gets out of sync.

Maybe fixes gio#265

[0] https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm46515148826720

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-09-08 13:25:17 +02:00
parent b3751dd9ab
commit c5d4e01e3d
+6 -8
View File
@@ -77,7 +77,7 @@ type x11Window struct {
wmName C.Atom
// "_NET_WM_STATE"
wmState C.Atom
// _NET_WM_STATE_FULLSCREEN"
// "_NET_WM_STATE_FULLSCREEN"
wmStateFullscreen C.Atom
}
stage system.Stage
@@ -190,20 +190,18 @@ func (w *x11Window) SetCursor(name pointer.CursorName) {
}
func (w *x11Window) SetWindowMode(mode WindowMode) {
var action C.long
switch mode {
case Windowed:
C.XDeleteProperty(w.x, w.xw, w.atoms.wmStateFullscreen)
action = 0 // _NET_WM_STATE_REMOVE
case Fullscreen:
C.XChangeProperty(w.x, w.xw, w.atoms.wmState, C.XA_ATOM,
32, C.PropModeReplace,
(*C.uchar)(unsafe.Pointer(&w.atoms.wmStateFullscreen)), 1,
)
action = 1 // _NET_WM_STATE_ADD
default:
return
}
w.config.Mode = mode
// "A Client wishing to change the state of a window MUST send
// a _NET_WM_STATE client message to the root window (see below)."
// a _NET_WM_STATE client message to the root window."
var xev C.XEvent
ev := (*C.XClientMessageEvent)(unsafe.Pointer(&xev))
*ev = C.XClientMessageEvent{
@@ -214,7 +212,7 @@ func (w *x11Window) SetWindowMode(mode WindowMode) {
format: 32,
}
arr := (*[5]C.long)(unsafe.Pointer(&ev.data))
arr[0] = 2 // _NET_WM_STATE_TOGGLE
arr[0] = action
arr[1] = C.long(w.atoms.wmStateFullscreen)
arr[2] = 0
arr[3] = 1 // application