diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1a45ca..b2e57ae8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Add support for `Touch` for emscripten backend. - Added support for `DroppedFile`, `HoveredFile`, and `HoveredFileCancelled` to X11 backend. - **Breaking:** `unix::WindowExt` no longer returns pointers for things that aren't actually pointers; `get_xlib_window` now returns `Option` and `get_xlib_screen_id` returns `Option`. Additionally, methods that previously returned `libc::c_void` have been changed to return `std::os::raw::c_void`, which are not interchangeable types, so users wanting the former will need to explicitly cast. +- Added `set_decorations` method to `Window` to allow decorations to be toggled after the window is built. Presently only implemented on X11. # Version 0.9.0 (2017-12-01) diff --git a/src/platform/android/mod.rs b/src/platform/android/mod.rs index b8656bc8..1ebd534b 100644 --- a/src/platform/android/mod.rs +++ b/src/platform/android/mod.rs @@ -44,7 +44,7 @@ impl EventsLoop { MonitorId } - + pub fn poll_events(&mut self, mut callback: F) where F: FnMut(::Event) { @@ -101,7 +101,7 @@ impl EventsLoop { None } }; - + if let Some(event) = e { callback(event); } @@ -288,6 +288,11 @@ impl Window { // Android has single screen maximized apps so nothing to do } + #[inline] + pub fn set_decorations(&self, _decorations: bool) { + // N/A + } + #[inline] pub fn get_current_monitor(&self) -> RootMonitorId { RootMonitorId{inner: MonitorId} diff --git a/src/platform/emscripten/mod.rs b/src/platform/emscripten/mod.rs index 9b3bd131..5b06417b 100644 --- a/src/platform/emscripten/mod.rs +++ b/src/platform/emscripten/mod.rs @@ -517,6 +517,11 @@ impl Window { // iOS has single screen maximized apps so nothing to do } + #[inline] + pub fn set_decorations(&self, _decorations: bool) { + // N/A + } + #[inline] pub fn get_current_monitor(&self) -> ::MonitorId { ::MonitorId{inner: MonitorId} @@ -693,7 +698,7 @@ fn key_translate_virt(input: [ffi::EM_UTF8; ffi::EM_HTML5_SHORT_STRING_LEN_BYTES "PreviousCandidate" => None, "Process" => None, "SingleCandidate" => None, - + "HangulMode" => None, "HanjaMode" => None, "JunjaMode" => None, diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index e6b4dc45..6fbaff25 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -354,6 +354,11 @@ impl Window { // iOS has single screen maximized apps so nothing to do } + #[inline] + pub fn set_decorations(&self, _decorations: bool) { + // N/A + } + #[inline] pub fn get_current_monitor(&self) -> RootMonitorId { RootMonitorId{inner: MonitorId} diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index fc88a3a8..d8e466a6 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -248,7 +248,9 @@ impl Window { pub fn set_maximized(&self, maximized: bool) { match self { &Window::X(ref w) => w.set_maximized(maximized), - &Window::Wayland(ref _w) => {}, + &Window::Wayland(ref _w) => { + unimplemented!(); + } } } @@ -256,7 +258,19 @@ impl Window { pub fn set_fullscreen(&self, monitor: Option) { match self { &Window::X(ref w) => w.set_fullscreen(monitor), - &Window::Wayland(ref _w) => {}, + &Window::Wayland(ref _w) => { + unimplemented!(); + } + } + } + + #[inline] + pub fn set_decorations(&self, decorations: bool) { + match self { + &Window::X(ref w) => w.set_decorations(decorations), + &Window::Wayland(ref _w) => { + unimplemented!(); + } } } diff --git a/src/platform/linux/x11/window.rs b/src/platform/linux/x11/window.rs index f25a41dd..aeceb89a 100644 --- a/src/platform/linux/x11/window.rs +++ b/src/platform/linux/x11/window.rs @@ -432,40 +432,36 @@ impl Window2 { pub fn set_decorations(&self, decorations: bool) { #[repr(C)] struct MotifWindowHints { - flags: u32, - functions: u32, - decorations: u32, - input_mode: i32, - status: u32, + flags: c_ulong, + functions: c_ulong, + decorations: c_ulong, + input_mode: c_long, + status: c_ulong, } - let wm_hints = unsafe { - (self.x.display.xlib.XInternAtom)(self.x.display.display, b"_MOTIF_WM_HINTS\0".as_ptr() as *const _, 0) + let wm_hints = unsafe { util::get_atom(&self.x.display, b"_MOTIF_WM_HINTS\0") } + .expect("Failed to call XInternAtom (_MOTIF_WM_HINTS)"); + + let hints = MotifWindowHints { + flags: 2, // MWM_HINTS_DECORATIONS + functions: 0, + decorations: decorations as _, + input_mode: 0, + status: 0, }; - self.x.display.check_errors().expect("Failed to call XInternAtom"); - if !decorations { - let hints = MotifWindowHints { - flags: 2, // MWM_HINTS_DECORATIONS - functions: 0, - decorations: 0, - input_mode: 0, - status: 0, - }; - - unsafe { - (self.x.display.xlib.XChangeProperty)( - self.x.display.display, self.x.window, - wm_hints, wm_hints, 32 /* Size of elements in struct */, - ffi::PropModeReplace, &hints as *const MotifWindowHints as *const u8, - 5 /* Number of elements in struct */); - (self.x.display.xlib.XFlush)(self.x.display.display); - } - } else { - unsafe { - (self.x.display.xlib.XDeleteProperty)(self.x.display.display, self.x.window, wm_hints); - (self.x.display.xlib.XFlush)(self.x.display.display); - } + unsafe { + (self.x.display.xlib.XChangeProperty)( + self.x.display.display, + self.x.window, + wm_hints, + wm_hints, + 32, // struct members are longs + ffi::PropModeReplace, + &hints as *const _ as *const u8, + 5 // struct has 5 members + ); + (self.x.display.xlib.XFlush)(self.x.display.display); } self.x.display.check_errors().expect("Failed to set decorations"); diff --git a/src/platform/macos/window.rs b/src/platform/macos/window.rs index 63d2168a..1eb41235 100644 --- a/src/platform/macos/window.rs +++ b/src/platform/macos/window.rs @@ -643,6 +643,11 @@ impl Window2 { unimplemented!() } + #[inline] + pub fn set_decorations(&self, _decorations: bool) { + unimplemented!() + } + #[inline] pub fn get_current_monitor(&self) -> RootMonitorId { unimplemented!() diff --git a/src/platform/windows/window.rs b/src/platform/windows/window.rs index d3d75921..8c82c627 100644 --- a/src/platform/windows/window.rs +++ b/src/platform/windows/window.rs @@ -45,7 +45,7 @@ impl Window { { let mut w_attr = Some(w_attr.clone()); let mut pl_attr = Some(pl_attr.clone()); - + let (tx, rx) = channel(); events_loop.execute_in_thread(move |inserter| { @@ -288,6 +288,11 @@ impl Window { unimplemented!() } + #[inline] + pub fn set_decorations(&self, _decorations: bool) { + unimplemented!() + } + #[inline] pub fn get_current_monitor(&self) -> RootMonitorId { unimplemented!() @@ -298,7 +303,7 @@ impl Drop for Window { #[inline] fn drop(&mut self) { unsafe { - // We are sending WM_CLOSE, and our callback will process this by calling DefWindowProcW, + // We are sending WM_CLOSE, and our callback will process this by calling DefWindowProcW, // which in turn will send a WM_DESTROY. user32::PostMessageW(self.window.0, winapi::WM_CLOSE, 0, 0); } diff --git a/src/window.rs b/src/window.rs index d4e11aed..d57c6181 100644 --- a/src/window.rs +++ b/src/window.rs @@ -313,6 +313,12 @@ impl Window { self.window.set_fullscreen(monitor) } + /// Turn window decorations on or off. + #[inline] + pub fn set_decorations(&self, decorations: bool) { + self.window.set_decorations(decorations) + } + /// Returns the current monitor the window is on or the primary monitor is nothing /// matches pub fn get_current_monitor(&self) -> MonitorId {