aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-01-16 18:11:06 +0100
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-01-16 18:19:56 +0100
commit4d729164c79f663465939ac404a9fe192cebc004 (patch)
treef3d24ca00ee8ec223098c19988b7f9ea1112160d /src
parent9ba16e31a9f65712035d28371c647b60f8ee37b1 (diff)
downloadglutin-4d729164c79f663465939ac404a9fe192cebc004.tar.gz
glutin-4d729164c79f663465939ac404a9fe192cebc004.zip
x11: Poll the window until it is really visible
Fixes #697 It seems that `XSync` doesn't really makes the window viewable. This feels hacky, other option to do it could be using `XIfEvent` or similar to listen to `MapNotify` events, but we'll have a loop still. In practice, this lasts between two and thre iterations on my machine, which is something not noticeable.
Diffstat (limited to 'src')
-rw-r--r--src/api/x11/window.rs31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs
index 2f700ce..de9cfb6 100644
--- a/src/api/x11/window.rs
+++ b/src/api/x11/window.rs
@@ -9,6 +9,8 @@ use std::sync::atomic::AtomicBool;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
use std::os::raw::c_long;
+use std::thread;
+use std::time::Duration;
use Api;
use ContextError;
@@ -642,15 +644,26 @@ impl Window {
let ref x_window: &XWindow = window.x.borrow();
// XSetInputFocus generates an error if the window is not visible,
- // therefore we call XSync before to make sure it's the case
- (display.xlib.XSync)(display.display, 0);
- (display.xlib.XSetInputFocus)(
- display.display,
- x_window.window,
- ffi::RevertToParent,
- ffi::CurrentTime
- );
- display.check_errors().expect("Failed to call XSetInputFocus");
+ // therefore we wait until it's the case.
+ loop {
+ let mut window_attributes = mem::uninitialized();
+ (display.xlib.XGetWindowAttributes)(display.display, x_window.window, &mut window_attributes);
+ display.check_errors().expect("Failed to call XGetWindowAttributes");
+
+ if window_attributes.map_state == ffi::IsViewable {
+ (display.xlib.XSetInputFocus)(
+ display.display,
+ x_window.window,
+ ffi::RevertToParent,
+ ffi::CurrentTime
+ );
+ display.check_errors().expect("Failed to call XSetInputFocus");
+ break;
+ }
+
+ // Wait about a frame to avoid too-busy waiting
+ thread::sleep(Duration::from_millis(16));
+ }
}
}