From 918dc6799269cc36268d4f71431344315a213ccb Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Sun, 25 Oct 2015 21:47:47 -0400 Subject: [PATCH 1/9] Fix issue #582 I switched `vsyncstart` and `vdisplay` again, as per the discussion on issue #582. --- src/api/x11/window.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 0196f672..8ab87ded 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -325,7 +325,7 @@ impl Window { let mode_to_switch_to = if window_attrs.monitor.is_some() { let matching_mode = (0 .. mode_num).map(|i| { let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m - }).find(|m| m.hdisplay == dimensions.0 as u16 && m.vsyncstart == dimensions.1 as u16); + }).find(|m| m.hdisplay == dimensions.0 as u16 && m.vdisplay == dimensions.1 as u16); if let Some(matching_mode) = matching_mode { Some(matching_mode) @@ -333,7 +333,7 @@ impl Window { } else { let m = (0 .. mode_num).map(|i| { let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m - }).find(|m| m.hdisplay >= dimensions.0 as u16 && m.vsyncstart == dimensions.1 as u16); + }).find(|m| m.hdisplay >= dimensions.0 as u16 && m.vdisplay == dimensions.1 as u16); match m { Some(m) => Some(m), From ed8dfa9a52e4034c50bf0fd87c89484bffb043f0 Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Sun, 25 Oct 2015 21:56:49 -0400 Subject: [PATCH 2/9] Fix issue #509 Focusing the newly created window seems to grab the keyboard. --- src/api/x11/window.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 8ab87ded..b6a96219 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -565,6 +565,16 @@ impl Window { input_handler: Mutex::new(XInputEventHandler::new(display, window, ic, window_attrs)) }; + unsafe { + let ref x_window: &XWindow = window.x.borrow(); + (display.xlib.XSetInputFocus)( + display.display, + x_window.window, + ffi::RevertToParent, + ffi::CurrentTime + ); + } + // returning Ok(window) } From 47df0e9eaa7f1231a07f86fc44426936c7a2589a Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Mon, 26 Oct 2015 03:40:37 -0400 Subject: [PATCH 3/9] Fix misbehaving fullscreen window --- src/api/x11/window.rs | 59 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index b6a96219..2a0badef 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -436,14 +436,14 @@ impl Window { } // switching to fullscreen - if let Some(mut mode_to_switch_to) = mode_to_switch_to { - window_attributes |= ffi::CWOverrideRedirect; - unsafe { - (display.xf86vmode.XF86VidModeSwitchToMode)(display.display, screen_id, &mut mode_to_switch_to); - (display.xf86vmode.XF86VidModeSetViewPort)(display.display, screen_id, 0, 0); - set_win_attr.override_redirect = 1; - } - } + // if let Some(mut mode_to_switch_to) = mode_to_switch_to { + // window_attributes |= ffi::CWOverrideRedirect; + // unsafe { + // (display.xf86vmode.XF86VidModeSwitchToMode)(display.display, screen_id, &mut mode_to_switch_to); + // (display.xf86vmode.XF86VidModeSetViewPort)(display.display, screen_id, 0, 0); + // set_win_attr.override_redirect = 1; + // } + // } // finally creating the window let window = unsafe { @@ -527,6 +527,49 @@ impl Window { let is_fullscreen = window_attrs.monitor.is_some(); + if is_fullscreen { + let state_atom = unsafe { + with_c_str("_NET_WM_STATE", |state| + (display.xlib.XInternAtom)(display.display, state, 0) + ) + }; + let fs_atom = unsafe { + with_c_str("_NET_WM_STATE_FULLSCREEN", |state_fullscreen| + (display.xlib.XInternAtom)(display.display, state_fullscreen, 0) + ) + }; + + let client_message_event = ffi::XClientMessageEvent { + type_: ffi::ClientMessage, + serial: 0, + send_event: 1, + display: display.display, + window: window, + message_type: state_atom, + format: 32, + data: { + let mut data = unsafe { + mem::transmute::<[libc::c_long; 5], ffi::ClientMessageData>([0; 5]) + }; + data.set_long(0, 1); + data.set_long(1, fs_atom as i64); + data.set_long(2, 0); + data + } + }; + let mut x_event = ffi::XEvent::from(client_message_event); + + unsafe { + (display.xlib.XSendEvent)( + display.display, + root, + 0, + ffi::SubstructureRedirectMask | ffi::SubstructureNotifyMask, + &mut x_event as *mut _ + ); + } + } + // finish creating the OpenGL context let context = match context { Prototype::Glx(ctxt) => { From 23a51040982358b6de24b3a3f70c8cbd4c311543 Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Mon, 26 Oct 2015 05:11:59 -0400 Subject: [PATCH 4/9] Comment fullscreen XClientMessage code --- src/api/x11/window.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 2a0badef..7ad29519 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -533,7 +533,7 @@ impl Window { (display.xlib.XInternAtom)(display.display, state, 0) ) }; - let fs_atom = unsafe { + let fullscreen_atom = unsafe { with_c_str("_NET_WM_STATE_FULLSCREEN", |state_fullscreen| (display.xlib.XInternAtom)(display.display, state_fullscreen, 0) ) @@ -542,18 +542,21 @@ impl Window { let client_message_event = ffi::XClientMessageEvent { type_: ffi::ClientMessage, serial: 0, - send_event: 1, + send_event: 1, // true because we are sending this through `XSendEvent` display: display.display, window: window, - message_type: state_atom, - format: 32, + message_type: state_atom, // the _NET_WM_STATE atom is sent to change the state of a window + format: 32, // view `data` as `c_long`s data: { + // TODO replace this with normal instantiation when x11-rs makes + // ClientMessageData instantiable. let mut data = unsafe { mem::transmute::<[libc::c_long; 5], ffi::ClientMessageData>([0; 5]) }; + // This first `long` is the action; `1` means add/set following property. data.set_long(0, 1); - data.set_long(1, fs_atom as i64); - data.set_long(2, 0); + // This second `long` is the property to set (fullscreen) + data.set_long(1, fullscreen_atom as i64); data } }; From 4f8095816ee43e99fc131375817033bd75c7288e Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Tue, 27 Oct 2015 00:33:48 -0400 Subject: [PATCH 5/9] Allow any mode larger than requested dimensions We were previously allowing only fullscreen modes which were exactly as tall as the requested dimensions, perhaps erroneously. --- src/api/x11/window.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 7ad29519..c8c0bf79 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -333,7 +333,7 @@ impl Window { } else { let m = (0 .. mode_num).map(|i| { let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m - }).find(|m| m.hdisplay >= dimensions.0 as u16 && m.vdisplay == dimensions.1 as u16); + }).find(|m| m.hdisplay >= dimensions.0 as u16 && m.vdisplay >= dimensions.1 as u16); match m { Some(m) => Some(m), From f9929fab2f3178cdbb5cd8bfb7492f942b766bbc Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Tue, 27 Oct 2015 03:07:37 -0400 Subject: [PATCH 6/9] Use mode when switching to fullscreen --- src/api/x11/window.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index c8c0bf79..3da4e7ba 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -435,16 +435,6 @@ impl Window { window_attributes |= ffi::CWBackPixel; } - // switching to fullscreen - // if let Some(mut mode_to_switch_to) = mode_to_switch_to { - // window_attributes |= ffi::CWOverrideRedirect; - // unsafe { - // (display.xf86vmode.XF86VidModeSwitchToMode)(display.display, screen_id, &mut mode_to_switch_to); - // (display.xf86vmode.XF86VidModeSetViewPort)(display.display, screen_id, 0, 0); - // set_win_attr.override_redirect = 1; - // } - // } - // finally creating the window let window = unsafe { let win = (display.xlib.XCreateWindow)(display.display, root, 0, 0, dimensions.0 as libc::c_uint, @@ -571,6 +561,22 @@ impl Window { &mut x_event as *mut _ ); } + + if let Some(mut mode_to_switch_to) = mode_to_switch_to { + unsafe { + (display.xf86vmode.XF86VidModeSwitchToMode)( + display.display, + screen_id, + &mut mode_to_switch_to + ); + } + } + else { + println!("[glutin] Unexpected state: `mode` is None creating fullscreen window"); + } + unsafe { + (display.xf86vmode.XF86VidModeSetViewPort)(display.display, screen_id, 0, 0); + } } // finish creating the OpenGL context From d1a573037441f62abac0e3966f0556063db14ec2 Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Tue, 27 Oct 2015 03:08:54 -0400 Subject: [PATCH 7/9] Remove deprecated comment --- src/api/x11/window.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 3da4e7ba..f7058416 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -319,9 +319,6 @@ impl Window { let xf86_desk_mode = *modes.offset(0); - // FIXME: `XF86VidModeModeInfo` is missing its `hskew` field. Therefore we point to - // `vsyncstart` instead of `vdisplay` as a temporary hack. - let mode_to_switch_to = if window_attrs.monitor.is_some() { let matching_mode = (0 .. mode_num).map(|i| { let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m From 10f5528c14ef93160470b781fadabcfd93659568 Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Tue, 27 Oct 2015 03:10:57 -0400 Subject: [PATCH 8/9] Fix using garbage memory --- src/api/x11/window.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index f7058416..24dca344 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -54,7 +54,7 @@ pub struct XWindow { pub context: Context, is_fullscreen: bool, screen_id: libc::c_int, - xf86_desk_mode: *mut ffi::XF86VidModeModeInfo, + xf86_desk_mode: ffi::XF86VidModeModeInfo, ic: ffi::XIC, im: ffi::XIM, colormap: ffi::Colormap, @@ -87,7 +87,7 @@ impl Drop for XWindow { let _lock = GLOBAL_XOPENIM_LOCK.lock().unwrap(); if self.is_fullscreen { - (self.display.xf86vmode.XF86VidModeSwitchToMode)(self.display.display, self.screen_id, self.xf86_desk_mode); + (self.display.xf86vmode.XF86VidModeSwitchToMode)(self.display.display, self.screen_id, &mut self.xf86_desk_mode); (self.display.xf86vmode.XF86VidModeSetViewPort)(self.display.display, self.screen_id, 0, 0); } @@ -317,7 +317,7 @@ impl Window { return Err(OsError(format!("Could not query the video modes"))); } - let xf86_desk_mode = *modes.offset(0); + let xf86_desk_mode: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(0)); let mode_to_switch_to = if window_attrs.monitor.is_some() { let matching_mode = (0 .. mode_num).map(|i| { From c068a770f0faec9a0fed199e9e9dfc0a00599e97 Mon Sep 17 00:00:00 2001 From: Adam Badawy Date: Tue, 27 Oct 2015 03:22:13 -0400 Subject: [PATCH 9/9] Update x11-dl --- Cargo.toml | 12 ++++++------ src/api/x11/window.rs | 6 +----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dacef718..e0dcaf39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,39 +85,39 @@ osmesa-sys = "0.0.5" wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] } wayland-kbd = "0.2.0" wayland-window = "0.1.0" -x11-dl = "~2.0" +x11-dl = "~2.2" [target.x86_64-unknown-linux-gnu.dependencies] osmesa-sys = "0.0.5" wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] } wayland-kbd = "0.2.0" wayland-window = "0.1.0" -x11-dl = "~2.0" +x11-dl = "~2.2" [target.arm-unknown-linux-gnueabihf.dependencies] osmesa-sys = "0.0.5" wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] } wayland-kbd = "0.2.0" wayland-window = "0.1.0" -x11-dl = "~2.0" +x11-dl = "~2.2" [target.aarch64-unknown-linux-gnu.dependencies] osmesa-sys = "0.0.5" wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] } wayland-kbd = "0.2.0" wayland-window = "0.1.0" -x11-dl = "~2.0" +x11-dl = "~2.2" [target.x86_64-unknown-dragonfly.dependencies] osmesa-sys = "0.0.5" wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] } wayland-kbd = "0.2.0" wayland-window = "0.1.0" -x11-dl = "~2.0" +x11-dl = "~2.2" [target.x86_64-unknown-freebsd.dependencies] osmesa-sys = "0.0.5" wayland-client = { version = "0.2.1", features = ["egl", "dlopen"] } wayland-kbd = "0.2.0" wayland-window = "0.1.0" -x11-dl = "~2.0" +x11-dl = "~2.2" diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 24dca344..cfe38d13 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -535,11 +535,7 @@ impl Window { message_type: state_atom, // the _NET_WM_STATE atom is sent to change the state of a window format: 32, // view `data` as `c_long`s data: { - // TODO replace this with normal instantiation when x11-rs makes - // ClientMessageData instantiable. - let mut data = unsafe { - mem::transmute::<[libc::c_long; 5], ffi::ClientMessageData>([0; 5]) - }; + let mut data = ffi::ClientMessageData::new(); // This first `long` is the action; `1` means add/set following property. data.set_long(0, 1); // This second `long` is the property to set (fullscreen)