(fullscreen: bool)
| 84 | static mut RELATIVE_MODE: bool = false; |
| 85 | |
| 86 | pub fn set_fullscreen(fullscreen: bool) { |
| 87 | unsafe { |
| 88 | // BLOOM_NO_FULLSCREEN=1 hard-disables the fullscreen path so |
| 89 | // benchmark harnesses on a 4K monitor don't silently 4× their |
| 90 | // pixel count when an inherited fullscreen Space leaks in. |
| 91 | if NO_FULLSCREEN && fullscreen { return; } |
| 92 | if DISPLAY.is_null() || X11_WINDOW == 0 { return; } |
| 93 | |
| 94 | let wm_state = x11::xlib::XInternAtom( |
| 95 | DISPLAY, |
| 96 | b"_NET_WM_STATE\0".as_ptr() as *const _, |
| 97 | 0, |
| 98 | ); |
| 99 | let wm_fullscreen = x11::xlib::XInternAtom( |
| 100 | DISPLAY, |
| 101 | b"_NET_WM_STATE_FULLSCREEN\0".as_ptr() as *const _, |
| 102 | 0, |
| 103 | ); |
| 104 | |
| 105 | let action = if fullscreen { 1 } else { 0 }; // _NET_WM_STATE_ADD / _REMOVE |
| 106 | |
| 107 | let mut event: x11::xlib::XClientMessageEvent = std::mem::zeroed(); |
| 108 | event.type_ = x11::xlib::ClientMessage; |
| 109 | event.window = X11_WINDOW; |
| 110 | event.message_type = wm_state; |
| 111 | event.format = 32; |
| 112 | event.data.set_long(0, action); |
| 113 | event.data.set_long(1, wm_fullscreen as i64); |
| 114 | event.data.set_long(2, 0); |
| 115 | event.data.set_long(3, 1); // source: normal application |
| 116 | |
| 117 | let root = x11::xlib::XDefaultRootWindow(DISPLAY); |
| 118 | x11::xlib::XSendEvent( |
| 119 | DISPLAY, |
| 120 | root, |
| 121 | 0, |
| 122 | x11::xlib::SubstructureRedirectMask | x11::xlib::SubstructureNotifyMask, |
| 123 | &mut event as *mut x11::xlib::XClientMessageEvent as *mut x11::xlib::XEvent, |
| 124 | ); |
| 125 | x11::xlib::XFlush(DISPLAY); |
| 126 | IS_FULLSCREEN = fullscreen; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | pub fn toggle_fullscreen() { |
| 131 | unsafe { set_fullscreen(!IS_FULLSCREEN); } |
no test coverage detected