From 7473d99c2f4038a36cb7848e0c08f89b47b219b3 Mon Sep 17 00:00:00 2001 From: Ivo Wetzel Date: Sun, 6 Mar 2016 20:47:10 +0100 Subject: [PATCH 01/33] Implement `min/max_dimensions` for x11 windows. Size hints are only being set for non-fullscreen windows, if `max_dimensions` are set they'll override the normal `dimensions` since X11 will not automatically resize the window after setting the size hints. `PSize` hint is currently set along with the `min/max` hints for good measure. --- src/api/x11/window.rs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 8cae2bef..86d6c929 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -310,11 +310,7 @@ impl Window { pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&Window>) -> Result { - let dimensions = window_attrs.dimensions.unwrap_or((800, 600)); - - // not implemented - assert!(window_attrs.min_dimensions.is_none()); - assert!(window_attrs.max_dimensions.is_none()); + let dimensions = window_attrs.max_dimensions.unwrap_or(window_attrs.dimensions.unwrap_or((800, 600))); let screen_id = match window_attrs.monitor { Some(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32, @@ -339,7 +335,7 @@ impl Window { 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); - + match m { Some(m) => Some(m), None => return Err(OsError(format!("Could not find a suitable graphics mode"))) @@ -589,6 +585,32 @@ impl Window { (display.xf86vmode.XF86VidModeSetViewPort)(display.display, screen_id, 0, 0); display.check_errors().expect("Failed to call XF86VidModeSetViewPort"); } + + } else { + + // set size hints + let mut size_hints: ffi::XSizeHints = unsafe { mem::zeroed() }; + size_hints.flags = ffi::PSize; + size_hints.width = dimensions.0 as i32; + size_hints.height = dimensions.1 as i32; + + if let Some(dimensions) = window_attrs.min_dimensions { + size_hints.flags |= ffi::PMinSize; + size_hints.min_width = dimensions.0 as i32; + size_hints.min_height = dimensions.1 as i32; + } + + if let Some(dimensions) = window_attrs.max_dimensions { + size_hints.flags |= ffi::PMaxSize; + size_hints.max_width = dimensions.0 as i32; + size_hints.max_height = dimensions.1 as i32; + } + + unsafe { + (display.xlib.XSetNormalHints)(display.display, window, &mut size_hints); + display.check_errors().expect("Failed to call XSetNormalHints"); + } + } // finish creating the OpenGL context From 1b7a3cd31febc38b4d0d39d06f99639469a5823d Mon Sep 17 00:00:00 2001 From: Ivo Wetzel Date: Fri, 25 Mar 2016 19:52:57 +0100 Subject: [PATCH 02/33] Correctly apply initial size constraints for x11 windows. --- src/api/x11/window.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index aeb7efe6..b84dc09e 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -3,7 +3,7 @@ use CreationError; use CreationError::OsError; use libc; use std::borrow::Borrow; -use std::{mem, ptr}; +use std::{mem, ptr, cmp}; use std::cell::Cell; use std::sync::atomic::AtomicBool; use std::collections::VecDeque; @@ -310,7 +310,23 @@ impl Window { pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&Window>) -> Result { - let dimensions = window_attrs.max_dimensions.unwrap_or(window_attrs.dimensions.unwrap_or((800, 600))); + let dimensions = { + + // x11 only applies constraints when the window is actively resized + // by the user, so we have to manually apply the initial constraints + let mut dimensions = window_attrs.dimensions.unwrap_or((800, 600)); + if let Some(max) = window_attrs.max_dimensions { + dimensions.0 = cmp::min(dimensions.0, max.0); + dimensions.1 = cmp::min(dimensions.1, max.1); + } + + if let Some(min) = window_attrs.min_dimensions { + dimensions.0 = cmp::max(dimensions.0, min.0); + dimensions.1 = cmp::max(dimensions.1, min.1); + } + dimensions + + }; let screen_id = match window_attrs.monitor { Some(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32, From 117069ef9023665085564c4c20a9525c9e139de2 Mon Sep 17 00:00:00 2001 From: Richard Lettich Date: Sun, 27 Mar 2016 14:39:20 -0400 Subject: [PATCH 03/33] Changed MouseMoved((i32, i32)) to MouseMoved(i32, i32), breaking change --- examples/grabbing.rs | 2 +- src/api/cocoa/mod.rs | 4 ++-- src/api/wayland/events.rs | 4 ++-- src/api/win32/callback.rs | 2 +- src/api/x11/input.rs | 2 +- src/events.rs | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/grabbing.rs b/examples/grabbing.rs index 485be78c..ad79f1be 100644 --- a/examples/grabbing.rs +++ b/examples/grabbing.rs @@ -35,7 +35,7 @@ fn main() { Event::Closed => break, - a @ Event::MouseMoved(_) => { + a @ Event::MouseMoved(_, _) => { println!("{:?}", a); }, diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index e9358055..da7c1ecb 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -848,8 +848,8 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { let view_rect = NSView::frame(*window.view); let scale_factor = window.hidpi_factor(); - Some(MouseMoved(((scale_factor * view_point.x as f32) as i32, - (scale_factor * (view_rect.size.height - view_point.y) as f32) as i32))) + Some(MouseMoved((scale_factor * view_point.x as f32) as i32, + (scale_factor * (view_rect.size.height - view_point.y) as f32) as i32)) }, NSKeyDown => { let mut events = VecDeque::new(); diff --git a/src/api/wayland/events.rs b/src/api/wayland/events.rs index 5e0c3fd0..92a0b95f 100644 --- a/src/api/wayland/events.rs +++ b/src/api/wayland/events.rs @@ -52,7 +52,7 @@ pub fn translate_event( if known_surfaces.contains(&surface) { focuses.pointer_on = Some(surface); focuses.pointer_at = Some((x, y)); - Some((GlutinEvent::MouseMoved((x as i32, y as i32)), surface)) + Some((GlutinEvent::MouseMoved(x as i32, y as i32), surface)) } else { None } @@ -65,7 +65,7 @@ pub fn translate_event( WlPointerEvent::Motion(_, x, y) => { if let Some(surface) = focuses.pointer_on { focuses.pointer_at = Some((x, y)); - Some((GlutinEvent::MouseMoved((x as i32, y as i32)), surface)) + Some((GlutinEvent::MouseMoved(x as i32, y as i32), surface)) } else { None } diff --git a/src/api/win32/callback.rs b/src/api/win32/callback.rs index 2d10699d..337611b8 100644 --- a/src/api/win32/callback.rs +++ b/src/api/win32/callback.rs @@ -126,7 +126,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, let x = winapi::GET_X_LPARAM(lparam) as i32; let y = winapi::GET_Y_LPARAM(lparam) as i32; - send_event(window, MouseMoved((x, y))); + send_event(window, MouseMoved(x, y)); 0 }, diff --git a/src/api/x11/input.rs b/src/api/x11/input.rs index a05b22e1..310f1bcb 100644 --- a/src/api/x11/input.rs +++ b/src/api/x11/input.rs @@ -241,7 +241,7 @@ impl XInputEventHandler { let new_cursor_pos = (event_data.event_x, event_data.event_y); if new_cursor_pos != self.current_state.cursor_pos { self.current_state.cursor_pos = new_cursor_pos; - Some(MouseMoved((new_cursor_pos.0 as i32, new_cursor_pos.1 as i32))) + Some(MouseMoved(new_cursor_pos.0 as i32, new_cursor_pos.1 as i32)) } else { None } diff --git a/src/events.rs b/src/events.rs index 9fff1fb7..d13a0bfe 100644 --- a/src/events.rs +++ b/src/events.rs @@ -28,7 +28,7 @@ pub enum Event { /// The cursor has moved on the window. /// /// The parameter are the (x,y) coords in pixels relative to the top-left corner of the window. - MouseMoved((i32, i32)), + MouseMoved(i32, i32), /// A mouse wheel movement or touchpad scroll occurred. MouseWheel(MouseScrollDelta, TouchPhase), From 1b313df1ea64c34b65f21f5d072515c3ae2b481d Mon Sep 17 00:00:00 2001 From: Ivo Wetzel Date: Wed, 30 Mar 2016 08:40:32 +0200 Subject: [PATCH 04/33] glx: Support non-conformant multisampling fbconfigs. --- src/api/glx/mod.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/api/glx/mod.rs b/src/api/glx/mod.rs index dcdc21c5..317d9ff3 100644 --- a/src/api/glx/mod.rs +++ b/src/api/glx/mod.rs @@ -360,6 +360,7 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli -> Result<(ffi::glx::types::GLXFBConfig, PixelFormat), ()> { let descriptor = { + let mut glx_non_conformant = false; let mut out: Vec = Vec::with_capacity(37); out.push(ffi::glx::X_RENDERABLE as c_int); @@ -382,15 +383,6 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli out.push(ffi::glx::RGBA_BIT as c_int); } - if let Some(hardware_accelerated) = reqs.hardware_accelerated { - out.push(ffi::glx::CONFIG_CAVEAT as c_int); - out.push(if hardware_accelerated { - ffi::glx::NONE as c_int - } else { - ffi::glx::SLOW_CONFIG as c_int - }); - } - if let Some(color) = reqs.color_bits { out.push(ffi::glx::RED_SIZE as c_int); out.push((color / 3) as c_int); @@ -425,6 +417,7 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli out.push(if multisampling == 0 { 0 } else { 1 }); out.push(ffi::glx_extra::SAMPLES_ARB as c_int); out.push(multisampling as c_int); + glx_non_conformant = true; } else { return Err(()); } @@ -452,6 +445,20 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli }, } + if let Some(hardware_accelerated) = reqs.hardware_accelerated { + let caveat = if hardware_accelerated { + ffi::glx::NONE as c_int + } else { + ffi::glx::SLOW_CONFIG as c_int + }; + out.push(ffi::glx::CONFIG_CAVEAT as c_int); + out.push(if glx_non_conformant { + caveat | ffi::glx::NON_CONFORMANT_CONFIG as c_int + } else { + caveat + }); + } + out.push(0); out }; From 136d3beed117df96364e6537ac467b47136d8541 Mon Sep 17 00:00:00 2001 From: tomaka Date: Wed, 6 Apr 2016 16:34:30 +0200 Subject: [PATCH 05/33] Publish 0.5.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f1434d17..21c58e9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glutin" -version = "0.4.9" +version = "0.5.0" authors = ["The glutin contributors, Pierre Krieger "] description = "Cross-platform OpenGL context provider." keywords = ["windowing", "opengl"] From c68c0d96b25d01571b131bdd53a61407b0405558 Mon Sep 17 00:00:00 2001 From: Pierre Chevalier Date: Wed, 13 Apr 2016 01:13:56 +0100 Subject: [PATCH 06/33] Fix pixel format support detection in glx. #748 * by accepting GLX_EXT_framebuffer_sRGB as a sRGB capable framebuffer * the new behaviour matches the wgl codel --- src/api/glx/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/api/glx/mod.rs b/src/api/glx/mod.rs index 317d9ff3..18f29386 100644 --- a/src/api/glx/mod.rs +++ b/src/api/glx/mod.rs @@ -430,6 +430,9 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli if extensions.split(' ').find(|&i| i == "GLX_ARB_framebuffer_sRGB").is_some() { out.push(ffi::glx_extra::FRAMEBUFFER_SRGB_CAPABLE_ARB as c_int); out.push(1); + } else if extensions.split(' ').find(|&i| i == "GLX_EXT_framebuffer_sRGB").is_some() { + out.push(ffi::glx_extra::FRAMEBUFFER_SRGB_CAPABLE_EXT as c_int); + out.push(1); } else { return Err(()); } @@ -498,7 +501,8 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli } else { None }, - srgb: get_attrib(ffi::glx_extra::FRAMEBUFFER_SRGB_CAPABLE_ARB as c_int) != 0, + srgb: get_attrib(ffi::glx_extra::FRAMEBUFFER_SRGB_CAPABLE_ARB as c_int) != 0 || + get_attrib(ffi::glx_extra::FRAMEBUFFER_SRGB_CAPABLE_EXT as c_int) != 0, }; Ok((fb_config, pf_desc)) From 18c065a2a188a01376d97926d3843503d4e6029a Mon Sep 17 00:00:00 2001 From: Pierre Chevalier Date: Wed, 13 Apr 2016 07:52:31 +0100 Subject: [PATCH 07/33] Publish 0.5.1 - to make the fix for #748 available to the repos downstream that need it --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 21c58e9c..c1a921a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glutin" -version = "0.5.0" +version = "0.5.1" authors = ["The glutin contributors, Pierre Krieger "] description = "Cross-platform OpenGL context provider." keywords = ["windowing", "opengl"] From b9065f56ba0c1fa9c55b6af31d765cc326456548 Mon Sep 17 00:00:00 2001 From: Boris-Chengbiao Zhou Date: Wed, 13 Apr 2016 13:37:58 +0200 Subject: [PATCH 08/33] glx: Always set CONFIG_CAVEAT to DONT_CARE --- src/api/glx/mod.rs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/api/glx/mod.rs b/src/api/glx/mod.rs index 18f29386..ae5b9c7a 100644 --- a/src/api/glx/mod.rs +++ b/src/api/glx/mod.rs @@ -360,7 +360,6 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli -> Result<(ffi::glx::types::GLXFBConfig, PixelFormat), ()> { let descriptor = { - let mut glx_non_conformant = false; let mut out: Vec = Vec::with_capacity(37); out.push(ffi::glx::X_RENDERABLE as c_int); @@ -417,7 +416,6 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli out.push(if multisampling == 0 { 0 } else { 1 }); out.push(ffi::glx_extra::SAMPLES_ARB as c_int); out.push(multisampling as c_int); - glx_non_conformant = true; } else { return Err(()); } @@ -448,19 +446,8 @@ unsafe fn choose_fbconfig(glx: &ffi::glx::Glx, extensions: &str, xlib: &ffi::Xli }, } - if let Some(hardware_accelerated) = reqs.hardware_accelerated { - let caveat = if hardware_accelerated { - ffi::glx::NONE as c_int - } else { - ffi::glx::SLOW_CONFIG as c_int - }; - out.push(ffi::glx::CONFIG_CAVEAT as c_int); - out.push(if glx_non_conformant { - caveat | ffi::glx::NON_CONFORMANT_CONFIG as c_int - } else { - caveat - }); - } + out.push(ffi::glx::CONFIG_CAVEAT as c_int); + out.push(ffi::glx::DONT_CARE as c_int); out.push(0); out From 7fb6450d17388097619bfb1e675e17c7bc2e3eaa Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 16 Apr 2016 20:37:53 +0200 Subject: [PATCH 09/33] Improve X11 cursor symbols handling 1. Make it non failing. Before we tried to call XFreeCursor with a cursor of 0 if we couldn't find a cursor. This has then caused a panic. 2. Introduce a system where multiple special cursors are tried in order to work with different themes and desktop environments. This way we get less often into the situation where we have to use a default cursor. 3. Also set names for some cursors that previously only had a placeholder. Fixes #765. Will fix https://github.com/servo/servo/issues/10475 as well. --- src/api/x11/window.rs | 102 ++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 38 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index b84dc09e..b5247955 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -841,50 +841,76 @@ impl Window { pub fn set_cursor(&self, cursor: MouseCursor) { unsafe { use std::ffi::CString; - let cursor_name = match cursor { - MouseCursor::Alias => "link", - MouseCursor::Arrow => "arrow", - MouseCursor::Cell => "plus", - MouseCursor::Copy => "copy", - MouseCursor::Crosshair => "crosshair", - MouseCursor::Default => "left_ptr", - MouseCursor::Grabbing => "grabbing", - MouseCursor::Hand | MouseCursor::Grab => "hand", - MouseCursor::Help => "question_arrow", - MouseCursor::Move => "move", - MouseCursor::NoDrop => "circle", - MouseCursor::NotAllowed => "crossed_circle", - MouseCursor::Progress => "left_ptr_watch", + let load = |name :&str| { + let c_string = CString::new(name.as_bytes().to_vec()).unwrap(); + return (self.x.display.xcursor.XcursorLibraryLoadCursor)(self.x.display.display, c_string.as_ptr()); + }; + let loadn = |names :&[&str]| { + for name in names.iter() { + let xcursor = load(*name); + if xcursor != 0 { + return xcursor; + } + } + return 0; + }; + // Try multiple names in some cases where the name + // differs on the desktop environments or themes. + // + // Try the better looking (or more suiting) names first. + let mut xcursor = match cursor { + MouseCursor::Alias => load("link"), + MouseCursor::Arrow => load("arrow"), + MouseCursor::Cell => load("plus"), + MouseCursor::Copy => load("copy"), + MouseCursor::Crosshair => load("crosshair"), + MouseCursor::Default => load("left_ptr"), + MouseCursor::Hand => load("hand1"), + MouseCursor::Help => load("question_arrow"), + MouseCursor::Move => load("move"), + MouseCursor::Grab => loadn(&["openhand", "grab"]), + MouseCursor::Grabbing => loadn(&["closedhand", "grabbing"]), + MouseCursor::Progress => load("left_ptr_watch"), + MouseCursor::AllScroll => load("all-scroll"), + MouseCursor::ContextMenu => load("context-menu"), + + MouseCursor::NoDrop => loadn(&["no-drop", "circle"]), + MouseCursor::NotAllowed => load("crossed_circle"), + /// Resize cursors - MouseCursor::EResize => "right_side", - MouseCursor::NResize => "top_side", - MouseCursor::NeResize => "top_right_corner", - MouseCursor::NwResize => "top_left_corner", - MouseCursor::SResize => "bottom_side", - MouseCursor::SeResize => "bottom_right_corner", - MouseCursor::SwResize => "bottom_left_corner", - MouseCursor::WResize => "left_side", - MouseCursor::EwResize | MouseCursor::ColResize => "h_double_arrow", - MouseCursor::NsResize | MouseCursor::RowResize => "v_double_arrow", - MouseCursor::NwseResize => "bd_double_arrow", - MouseCursor::NeswResize => "fd_double_arrow", + MouseCursor::EResize => load("right_side"), + MouseCursor::NResize => load("top_side"), + MouseCursor::NeResize => load("top_right_corner"), + MouseCursor::NwResize => load("top_left_corner"), + MouseCursor::SResize => load("bottom_side"), + MouseCursor::SeResize => load("bottom_right_corner"), + MouseCursor::SwResize => load("bottom_left_corner"), + MouseCursor::WResize => load("left_side"), + MouseCursor::EwResize => load("h_double_arrow"), + MouseCursor::NsResize => load("v_double_arrow"), + MouseCursor::NwseResize => loadn(&["bd_double_arrow", "size_bdiag"]), + MouseCursor::NeswResize => loadn(&["fd_double_arrow", "size_fdiag"]), + MouseCursor::ColResize => loadn(&["split_h", "h_double_arrow"]), + MouseCursor::RowResize => loadn(&["split_v", "v_double_arrow"]), - MouseCursor::Text | MouseCursor::VerticalText => "xterm", - MouseCursor::Wait => "watch", + MouseCursor::Text => loadn(&["text", "xterm"]), + MouseCursor::VerticalText => load("vertical-text"), - /// TODO: Find matching X11 cursors - MouseCursor::ContextMenu | MouseCursor::NoneCursor | - MouseCursor::AllScroll | MouseCursor::ZoomIn | - MouseCursor::ZoomOut => "left_ptr", + MouseCursor::Wait => load("watch"), + + MouseCursor::ZoomIn => load("zoom-in"), + MouseCursor::ZoomOut => load("zoom-out"), + + // TODO: Hide cursor + MouseCursor::NoneCursor => 0, }; - let c_string = CString::new(cursor_name.as_bytes().to_vec()).unwrap(); - let xcursor = (self.x.display.xcursor.XcursorLibraryLoadCursor)(self.x.display.display, c_string.as_ptr()); - self.x.display.check_errors().expect("Failed to call XcursorLibraryLoadCursor"); + (self.x.display.xlib.XDefineCursor)(self.x.display.display, self.x.window, xcursor); - (self.x.display.xlib.XFlush)(self.x.display.display); - (self.x.display.xlib.XFreeCursor)(self.x.display.display, xcursor); - self.x.display.check_errors().expect("Failed to call XDefineCursor"); + if xcursor != 0 { + (self.x.display.xlib.XFreeCursor)(self.x.display.display, xcursor); + } + self.x.display.check_errors().expect("Failed to set or free the cursor"); } } From 51aeb27d7e231227c34bc822da3e7f27b42b54f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 17 Apr 2016 17:32:34 +0200 Subject: [PATCH 10/33] x11: Add cursor hiding The created cursor could be cached and whatnot, but I'm not sure it deserves the complexity. --- src/api/x11/window.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index b5247955..85ad70df 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -11,6 +11,7 @@ use std::sync::{Arc, Mutex}; use std::os::raw::c_long; use std::thread; use std::time::Duration; +use x11_dl::xlib; use Api; use ContextError; @@ -902,8 +903,7 @@ impl Window { MouseCursor::ZoomIn => load("zoom-in"), MouseCursor::ZoomOut => load("zoom-out"), - // TODO: Hide cursor - MouseCursor::NoneCursor => 0, + MouseCursor::NoneCursor => self.create_empty_cursor(), }; (self.x.display.xlib.XDefineCursor)(self.x.display.display, self.x.window, xcursor); @@ -914,6 +914,34 @@ impl Window { } } + // TODO: This could maybe be cached. I don't think it's worth + // the complexity, since cursor changes are not so common, + // and this is just allocating a 1x1 pixmap... + fn create_empty_cursor(&self) -> xlib::Cursor { + use std::mem; + + let data = 0; + + unsafe { + let pixmap = (self.x.display.xlib.XCreateBitmapFromData)(self.x.display.display, self.x.window, &data, 1, 1); + if pixmap == 0 { + // Failed to allocate + return 0; + } + + // We don't care about this color, since it only fills bytes + // in the pixmap which are not 0 in the mask. + let dummy_color: xlib::XColor = mem::uninitialized(); + let cursor = (self.x.display.xlib.XCreatePixmapCursor)(self.x.display.display, + pixmap, + pixmap, + &dummy_color as *const _ as *mut _, + &dummy_color as *const _ as *mut _, 0, 0); + (self.x.display.xlib.XFreePixmap)(self.x.display.display, pixmap); + cursor + } + } + pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> { use CursorState::{ Grab, Normal, Hide }; From 0918fe4d9c3639d1fa5fdfae0aad8c229d40ddc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 17 Apr 2016 18:14:53 +0200 Subject: [PATCH 11/33] x11: Refactor NoneCursor logic so it applies to CursorState::Hide too --- src/api/x11/window.rs | 66 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index 85ad70df..dc7fa62b 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -11,7 +11,6 @@ use std::sync::{Arc, Mutex}; use std::os::raw::c_long; use std::thread; use std::time::Duration; -use x11_dl::xlib; use Api; use ContextError; @@ -841,20 +840,14 @@ impl Window { pub fn set_cursor(&self, cursor: MouseCursor) { unsafe { - use std::ffi::CString; - let load = |name :&str| { - let c_string = CString::new(name.as_bytes().to_vec()).unwrap(); - return (self.x.display.xcursor.XcursorLibraryLoadCursor)(self.x.display.display, c_string.as_ptr()); + let load = |name: &str| { + self.load_cursor(name) }; - let loadn = |names :&[&str]| { - for name in names.iter() { - let xcursor = load(*name); - if xcursor != 0 { - return xcursor; - } - } - return 0; + + let loadn = |names: &[&str]| { + self.load_first_existing_cursor(names) }; + // Try multiple names in some cases where the name // differs on the desktop environments or themes. // @@ -914,14 +907,31 @@ impl Window { } } + fn load_cursor(&self, name: &str) -> ffi::Cursor { + use std::ffi::CString; + unsafe { + let c_string = CString::new(name.as_bytes()).unwrap(); + (self.x.display.xcursor.XcursorLibraryLoadCursor)(self.x.display.display, c_string.as_ptr()) + } + } + + fn load_first_existing_cursor(&self, names :&[&str]) -> ffi::Cursor { + for name in names.iter() { + let xcursor = self.load_cursor(name); + if xcursor != 0 { + return xcursor; + } + } + 0 + } + // TODO: This could maybe be cached. I don't think it's worth // the complexity, since cursor changes are not so common, // and this is just allocating a 1x1 pixmap... - fn create_empty_cursor(&self) -> xlib::Cursor { + fn create_empty_cursor(&self) -> ffi::Cursor { use std::mem; let data = 0; - unsafe { let pixmap = (self.x.display.xlib.XCreateBitmapFromData)(self.x.display.display, self.x.window, &data, 1, 1); if pixmap == 0 { @@ -931,7 +941,7 @@ impl Window { // We don't care about this color, since it only fills bytes // in the pixmap which are not 0 in the mask. - let dummy_color: xlib::XColor = mem::uninitialized(); + let dummy_color: ffi::XColor = mem::uninitialized(); let cursor = (self.x.display.xlib.XCreatePixmapCursor)(self.x.display.display, pixmap, pixmap, @@ -960,13 +970,10 @@ impl Window { }, Normal => {}, Hide => { + // NB: Calling XDefineCursor with None (aka 0) + // as a value resets the cursor to the default. unsafe { - let xcursor = (self.x.display.xlib.XCreateFontCursor)(self.x.display.display, 68/*XC_left_ptr*/); - self.x.display.check_errors().expect("Failed to call XCreateFontCursor"); - (self.x.display.xlib.XDefineCursor)(self.x.display.display, self.x.window, xcursor); - self.x.display.check_errors().expect("Failed to call XDefineCursor"); - (self.x.display.xlib.XFlush)(self.x.display.display); - (self.x.display.xlib.XFreeCursor)(self.x.display.display, xcursor); + (self.x.display.xlib.XDefineCursor)(self.x.display.display, self.x.window, 0); } }, } @@ -975,18 +982,13 @@ impl Window { match state { Normal => Ok(()), Hide => { - let data = &[0, 0, 0, 0, 0, 0, 0, 0]; unsafe { - let mut black = ffi::XColor { - red: 0, green: 0, blue: 0, - pad: 0, pixel: 0, flags: 0, - }; - let bitmap = (self.x.display.xlib.XCreateBitmapFromData)(self.x.display.display, self.x.window, data.as_ptr(), 8, 8); - let cursor = (self.x.display.xlib.XCreatePixmapCursor)(self.x.display.display, bitmap, bitmap, &mut black, &mut black, 0, 0); + let cursor = self.create_empty_cursor(); (self.x.display.xlib.XDefineCursor)(self.x.display.display, self.x.window, cursor); - self.x.display.check_errors().expect("Failed to call XDefineCursor"); - (self.x.display.xlib.XFreeCursor)(self.x.display.display, cursor); - (self.x.display.xlib.XFreePixmap)(self.x.display.display, bitmap); + if cursor != 0 { + (self.x.display.xlib.XFreeCursor)(self.x.display.display, cursor); + } + self.x.display.check_errors().expect("Failed to call XDefineCursor or free the empty cursor"); } Ok(()) }, From dc49156fe6bd2d15c4bd5e5f9e1ff6f3ffe7d334 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 28 Apr 2016 19:30:44 -0400 Subject: [PATCH 12/33] Allow OSX WindowBuilder to specify 'activation behavior'. --- Cargo.toml | 2 +- src/api/cocoa/mod.rs | 14 ++++++++----- src/lib.rs | 17 +++++++++++++++- src/os/macos.rs | 48 +++++++++++++++++++++++++++++++++++++++++++- src/window.rs | 16 +-------------- 5 files changed, 74 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c1a921a6..37a2b38c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ objc = "0.2" [target.x86_64-apple-darwin.dependencies] objc = "0.2" cgl = "0.1" -cocoa = "0.3" +cocoa = "0.3.2" core-foundation = "0" core-graphics = "0.3" diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index da7c1ecb..3c4d802f 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -15,6 +15,7 @@ use ReleaseBehavior; use Robustness; use WindowAttributes; use native_monitor::NativeMonitorId; +use os::macos::ActivationPolicy; use objc::runtime::{Class, Object, Sel, BOOL, YES, NO}; use objc::declare::ClassDecl; @@ -181,7 +182,9 @@ impl Drop for WindowDelegate { } #[derive(Default)] -pub struct PlatformSpecificWindowBuilderAttributes; +pub struct PlatformSpecificWindowBuilderAttributes { + pub activation_policy: ActivationPolicy, +} pub struct Window { view: IdRef, @@ -276,7 +279,8 @@ impl<'a> Iterator for WaitEventsIterator<'a> { impl Window { pub fn new(win_attribs: &WindowAttributes, pf_reqs: &PixelFormatRequirements, - opengl: &GlAttributes<&Window>, _: &PlatformSpecificWindowBuilderAttributes) + opengl: &GlAttributes<&Window>, + pl_attribs: &PlatformSpecificWindowBuilderAttributes) -> Result { if opengl.sharing.is_some() { @@ -294,7 +298,7 @@ impl Window { _ => () } - let app = match Window::create_app() { + let app = match Window::create_app(pl_attribs.activation_policy) { Some(app) => app, None => { return Err(OsError(format!("Couldn't create NSApplication"))); }, }; @@ -359,13 +363,13 @@ impl Window { Ok(window) } - fn create_app() -> Option { + fn create_app(activation_policy: ActivationPolicy) -> Option { unsafe { let app = NSApp(); if app == nil { None } else { - app.setActivationPolicy_(NSApplicationActivationPolicyRegular); + app.setActivationPolicy_(activation_policy.into()); app.finishLaunching(); Some(app) } diff --git a/src/lib.rs b/src/lib.rs index fb03bed6..ff5d52e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,7 @@ extern crate wayland_client; pub use events::*; pub use headless::{HeadlessRendererBuilder, HeadlessContext}; -pub use window::{WindowBuilder, WindowProxy, PollEventsIterator, WaitEventsIterator}; +pub use window::{WindowProxy, PollEventsIterator, WaitEventsIterator}; pub use window::{AvailableMonitorsIter, MonitorId, get_available_monitors, get_primary_monitor}; pub use native_monitor::NativeMonitorId; @@ -105,6 +105,21 @@ pub struct Window { window: platform::Window, } +/// Object that allows you to build windows. +pub struct WindowBuilder<'a> { + /// The attributes to use to create the window. + pub window: WindowAttributes, + + /// The attributes to use to create the context. + pub opengl: GlAttributes<&'a platform::Window>, + + // Should be made public once it's stabilized. + pf_reqs: PixelFormatRequirements, + + /// Platform-specific configuration. + platform_specific: platform::PlatformSpecificWindowBuilderAttributes, +} + /// Trait that describes objects that have access to an OpenGL context. pub trait GlContext { /// Sets the context as the current context. diff --git a/src/os/macos.rs b/src/os/macos.rs index 16ffe33c..06ea55c2 100644 --- a/src/os/macos.rs +++ b/src/os/macos.rs @@ -1,7 +1,9 @@ #![cfg(target_os = "macos")] +use std::convert::From; use std::os::raw::c_void; -use Window; +use cocoa::appkit::NSApplicationActivationPolicy; +use {Window, WindowBuilder}; /// Additional methods on `Window` that are specific to MacOS. pub trait WindowExt { @@ -17,3 +19,47 @@ impl WindowExt for Window { self.window.platform_window() as *mut c_void } } + +/// Corresponds to `NSApplicationActivationPolicy`. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ActivationPolicy { + /// Corresponds to `NSApplicationActivationPolicyRegular`. + Regular, + /// Corresponds to `NSApplicationActivationPolicyAccessory`. + Accessory, + /// Corresponds to `NSApplicationActivationPolicyProhibited`. + Prohibited, +} + +impl Default for ActivationPolicy { + fn default() -> Self { + ActivationPolicy::Regular + } +} + +impl From for NSApplicationActivationPolicy { + fn from(activation_policy: ActivationPolicy) -> Self { + match activation_policy { + ActivationPolicy::Regular => + NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular, + ActivationPolicy::Accessory => + NSApplicationActivationPolicy::NSApplicationActivationPolicyAccessory, + ActivationPolicy::Prohibited => + NSApplicationActivationPolicy::NSApplicationActivationPolicyProhibited, + } + } +} + +/// Additional methods on `WindowBuilder` that are specific to MacOS. +pub trait WindowBuilderExt<'a> { + fn with_activation_policy(mut self, activation_policy: ActivationPolicy) -> WindowBuilder<'a>; +} + +impl<'a> WindowBuilderExt<'a> for WindowBuilder<'a> { + /// Sets the activation policy for the window being built + #[inline] + fn with_activation_policy(mut self, activation_policy: ActivationPolicy) -> WindowBuilder<'a> { + self.platform_specific.activation_policy = activation_policy; + self + } +} diff --git a/src/window.rs b/src/window.rs index 6d2f0d3b..8e82c1db 100644 --- a/src/window.rs +++ b/src/window.rs @@ -16,26 +16,12 @@ use PixelFormatRequirements; use Robustness; use Window; use WindowAttributes; +use WindowBuilder; use native_monitor::NativeMonitorId; use libc; use platform; -/// Object that allows you to build windows. -pub struct WindowBuilder<'a> { - /// The attributes to use to create the window. - pub window: WindowAttributes, - - /// The attributes to use to create the context. - pub opengl: GlAttributes<&'a platform::Window>, - - // Should be made public once it's stabilized. - pf_reqs: PixelFormatRequirements, - - /// Platform-specific configuration. - platform_specific: platform::PlatformSpecificWindowBuilderAttributes, -} - impl<'a> WindowBuilder<'a> { /// Initializes a new `WindowBuilder` with default values. #[inline] From 523140ed7481930251e9d499414d02af95c807dd Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 2 May 2016 14:58:52 -0700 Subject: [PATCH 13/33] Use cfg syntax for target-specific dependencies --- Cargo.toml | 102 +++-------------------------------------------------- 1 file changed, 5 insertions(+), 97 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 37a2b38c..db9cb1ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,32 +18,20 @@ shared_library = "0.1.0" [build-dependencies] gl_generator = "0.5" -[target.arm-linux-androideabi.dependencies.android_glue] +[target.'cfg(target_os = "android")'.dependencies.android_glue] version = "0.1" -[target.i386-apple-ios.dependencies] +[target.'cfg(target_os = "ios")'.dependencies] objc = "0.2" -[target.x86_64-apple-ios.dependencies] -objc = "0.2" - -[target.aarch64-apple-ios.dependencies] -objc = "0.2" - -[target.armv7s-apple-ios.dependencies] -objc = "0.2" - -[target.armv7-apple-ios.dependencies] -objc = "0.2" - -[target.x86_64-apple-darwin.dependencies] +[target.'cfg(target_os = "macos")'.dependencies] objc = "0.2" cgl = "0.1" cocoa = "0.3.2" core-foundation = "0" core-graphics = "0.3" -[target.i686-pc-windows-gnu.dependencies] +[target.'cfg(target_os = "windows")'.dependencies] winapi = "0.2" shell32-sys = "0.1" gdi32-sys = "0.1" @@ -51,87 +39,7 @@ user32-sys = "~0.1.2" kernel32-sys = "0.2" dwmapi-sys = "0.1" -[target.i686-pc-windows-msvc.dependencies] -winapi = "0.2" -shell32-sys = "0.1" -gdi32-sys = "0.1" -user32-sys = "~0.1.2" -kernel32-sys = "0.2" -dwmapi-sys = "0.1" - -[target.x86_64-pc-windows-gnu.dependencies] -winapi = "0.2" -shell32-sys = "0.1" -gdi32-sys = "0.1" -user32-sys = "~0.1.2" -kernel32-sys = "0.2" -dwmapi-sys = "0.1" - -[target.x86_64-pc-windows-msvc.dependencies] -winapi = "0.2" -shell32-sys = "0.1" -gdi32-sys = "0.1" -user32-sys = "~0.1.2" -kernel32-sys = "0.2" -dwmapi-sys = "0.1" - -[target.i686-unknown-linux-gnu.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.i586-unknown-linux-gnu.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.x86_64-unknown-linux-gnu.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.arm-unknown-linux-gnueabihf.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.armv7-unknown-linux-gnueabihf.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.aarch64-unknown-linux-gnu.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.x86_64-unknown-dragonfly.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.x86_64-unknown-freebsd.dependencies] -osmesa-sys = "0.0.5" -wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } -wayland-kbd = "0.3.3" -wayland-window = "0.2.2" -x11-dl = "~2.4" - -[target.x86_64-unknown-openbsd.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd"))'.dependencies] osmesa-sys = "0.0.5" wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } wayland-kbd = "0.3.3" From 386db740935ddb0b9e04ab6883888faffd4e9cc8 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 2 May 2016 15:05:45 -0700 Subject: [PATCH 14/33] Update lazy_static, osmesa-sys, and x11-dl --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index db9cb1ee..ddf68447 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ documentation = "https://tomaka.github.io/glutin/" build = "build.rs" [dependencies] -lazy_static = "0.1.10" +lazy_static = "0.2.0" libc = "0.2" shared_library = "0.1.0" @@ -40,8 +40,8 @@ kernel32-sys = "0.2" dwmapi-sys = "0.1" [target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd"))'.dependencies] -osmesa-sys = "0.0.5" +osmesa-sys = "0.1.0" wayland-client = { version = "0.5.4", features = ["egl", "dlopen"] } wayland-kbd = "0.3.3" wayland-window = "0.2.2" -x11-dl = "~2.4" +x11-dl = "2.4" From 18f846403b7f1893510744a58d9b347122658411 Mon Sep 17 00:00:00 2001 From: Andrey Lesnikov Date: Fri, 6 May 2016 00:01:40 +0300 Subject: [PATCH 15/33] Updated to android_glue 0.2 --- Cargo.toml | 2 +- src/api/android/ffi.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ddf68447..173b6a97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ shared_library = "0.1.0" gl_generator = "0.5" [target.'cfg(target_os = "android")'.dependencies.android_glue] -version = "0.1" +version = "0.2" [target.'cfg(target_os = "ios")'.dependencies] objc = "0.2" diff --git a/src/api/android/ffi.rs b/src/api/android/ffi.rs index 1398b772..af8c50b3 100644 --- a/src/api/android/ffi.rs +++ b/src/api/android/ffi.rs @@ -4,6 +4,7 @@ #![allow(non_upper_case_globals)] use libc; +use std::os::raw; #[link(name = "android")] #[link(name = "EGL")] @@ -13,12 +14,12 @@ extern {} /** * asset_manager.h */ -pub type AAssetManager = (); +pub type AAssetManager = raw::c_void; /** * native_window.h */ -pub type ANativeWindow = (); +pub type ANativeWindow = raw::c_void; extern { pub fn ANativeWindow_getHeight(window: *const ANativeWindow) -> libc::int32_t; From 54f442ea06e26654438c4f3acdbacca1b2b1cefe Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Sun, 8 May 2016 09:28:42 +0200 Subject: [PATCH 16/33] Generalize WindowBuilder::with_title --- examples/fullscreen.rs | 2 +- src/window.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs index 92d32a32..8671c9e4 100644 --- a/examples/fullscreen.rs +++ b/examples/fullscreen.rs @@ -32,7 +32,7 @@ fn main() { }; let window = glutin::WindowBuilder::new() - .with_title("Hello world!".to_string()) + .with_title("Hello world!") .with_fullscreen(monitor) .build() .unwrap(); diff --git a/src/window.rs b/src/window.rs index 8e82c1db..4cac1ce0 100644 --- a/src/window.rs +++ b/src/window.rs @@ -63,8 +63,8 @@ impl<'a> WindowBuilder<'a> { /// Requests a specific title for the window. #[inline] - pub fn with_title(mut self, title: String) -> WindowBuilder<'a> { - self.window.title = title; + pub fn with_title>(mut self, title: T) -> WindowBuilder<'a> { + self.window.title = title.into(); self } From cf02e7f1f44eebaaee939b8267b9457094d9bc6b Mon Sep 17 00:00:00 2001 From: tomaka Date: Thu, 19 May 2016 11:14:19 +0200 Subject: [PATCH 17/33] Publish 0.5.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ddf68447..467d1235 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glutin" -version = "0.5.1" +version = "0.5.2" authors = ["The glutin contributors, Pierre Krieger "] description = "Cross-platform OpenGL context provider." keywords = ["windowing", "opengl"] From e0f36b80c9bf29bbf3306a617614f6913b705a10 Mon Sep 17 00:00:00 2001 From: Jan Segre Date: Mon, 23 May 2016 03:17:31 -0300 Subject: [PATCH 18/33] Make `WindowBuilder` and `HeadlessRendererBuilder` derive `Clone`. --- src/api/android/mod.rs | 4 ++-- src/api/cocoa/headless.rs | 2 +- src/api/cocoa/mod.rs | 2 +- src/api/ios/mod.rs | 2 +- src/headless.rs | 1 + src/lib.rs | 1 + src/platform/emscripten/mod.rs | 4 ++-- src/platform/ios/mod.rs | 2 +- src/platform/linux/api_dispatch.rs | 2 +- src/platform/linux/mod.rs | 2 +- src/platform/windows/mod.rs | 4 ++-- 11 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/api/android/mod.rs b/src/api/android/mod.rs index 433472c5..2c17d927 100644 --- a/src/api/android/mod.rs +++ b/src/api/android/mod.rs @@ -65,9 +65,9 @@ impl MonitorId { } } -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes; -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; pub struct PollEventsIterator<'a> { diff --git a/src/api/cocoa/headless.rs b/src/api/cocoa/headless.rs index ac6c4e03..8d89e404 100644 --- a/src/api/cocoa/headless.rs +++ b/src/api/cocoa/headless.rs @@ -13,7 +13,7 @@ use cocoa::appkit::*; use PixelFormat; use api::cocoa::helpers; -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; pub struct HeadlessContext { diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index 3c4d802f..79f2b71c 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -181,7 +181,7 @@ impl Drop for WindowDelegate { } } -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes { pub activation_policy: ActivationPolicy, } diff --git a/src/api/ios/mod.rs b/src/api/ios/mod.rs index afcc6f42..8bee5134 100644 --- a/src/api/ios/mod.rs +++ b/src/api/ios/mod.rs @@ -177,7 +177,7 @@ impl MonitorId { } } -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes; impl Window { diff --git a/src/headless.rs b/src/headless.rs index 8ea4141a..31a9f5e4 100644 --- a/src/headless.rs +++ b/src/headless.rs @@ -11,6 +11,7 @@ use Robustness; use platform; /// Object that allows you to build headless contexts. +#[derive(Clone)] pub struct HeadlessRendererBuilder<'a> { /// The dimensions to use. pub dimensions: (u32, u32), diff --git a/src/lib.rs b/src/lib.rs index ff5d52e4..a10957d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,6 +106,7 @@ pub struct Window { } /// Object that allows you to build windows. +#[derive(Clone)] pub struct WindowBuilder<'a> { /// The attributes to use to create the window. pub window: WindowAttributes, diff --git a/src/platform/emscripten/mod.rs b/src/platform/emscripten/mod.rs index ce8d201c..22cb5653 100644 --- a/src/platform/emscripten/mod.rs +++ b/src/platform/emscripten/mod.rs @@ -58,7 +58,7 @@ impl GlContext for HeadlessContext { unsafe impl Send for HeadlessContext {} unsafe impl Sync for HeadlessContext {} -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes; -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index 2e6fbec0..0b1a5509 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -8,7 +8,7 @@ use ContextError; pub use api::ios::*; -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; pub struct HeadlessContext(i32); diff --git a/src/platform/linux/api_dispatch.rs b/src/platform/linux/api_dispatch.rs index 2e135e24..54e0186a 100644 --- a/src/platform/linux/api_dispatch.rs +++ b/src/platform/linux/api_dispatch.rs @@ -22,7 +22,7 @@ use api::x11::XConnection; use api::x11::XError; use api::x11::XNotSupported; -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes; enum Backend { diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 18658352..31a34147 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -15,7 +15,7 @@ pub use self::api_dispatch::{WaitEventsIterator, PollEventsIterator}; pub use self::api_dispatch::PlatformSpecificWindowBuilderAttributes; mod api_dispatch; -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; pub struct HeadlessContext(OsMesaContext); diff --git a/src/platform/windows/mod.rs b/src/platform/windows/mod.rs index 0c78322f..f5fa6fd8 100644 --- a/src/platform/windows/mod.rs +++ b/src/platform/windows/mod.rs @@ -51,9 +51,9 @@ lazy_static! { }; } -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificWindowBuilderAttributes; -#[derive(Default)] +#[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; /// The Win32 implementation of the main `Window` object. From 3958cd719200c3904b7166033abeafa1a9481953 Mon Sep 17 00:00:00 2001 From: tomaka Date: Mon, 13 Jun 2016 10:34:35 +0200 Subject: [PATCH 19/33] Publish 0.6.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1f3bb61b..9496e861 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glutin" -version = "0.5.2" +version = "0.6.0" authors = ["The glutin contributors, Pierre Krieger "] description = "Cross-platform OpenGL context provider." keywords = ["windowing", "opengl"] From 7a8429e49913147a3b5e28b7e35478ac3ddd0dff Mon Sep 17 00:00:00 2001 From: Andrey Lesnikov Date: Sun, 19 Jun 2016 11:24:26 +0300 Subject: [PATCH 20/33] android: Fixed Window::get_pixel_format --- src/api/android/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/android/mod.rs b/src/api/android/mod.rs index 2c17d927..43953fcc 100644 --- a/src/api/android/mod.rs +++ b/src/api/android/mod.rs @@ -231,7 +231,7 @@ impl Window { #[inline] pub fn get_pixel_format(&self) -> PixelFormat { - unimplemented!(); + self.context.get_pixel_format() } #[inline] @@ -289,7 +289,7 @@ impl GlContext for Window { #[inline] fn get_pixel_format(&self) -> PixelFormat { - self.context.get_pixel_format() + self.get_pixel_format() } } From 50b2b4d351ef9df131c332099c5b36a9f7865dc5 Mon Sep 17 00:00:00 2001 From: tomaka Date: Sun, 19 Jun 2016 12:53:28 +0200 Subject: [PATCH 21/33] Publish 0.6.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9496e861..a2738804 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glutin" -version = "0.6.0" +version = "0.6.1" authors = ["The glutin contributors, Pierre Krieger "] description = "Cross-platform OpenGL context provider." keywords = ["windowing", "opengl"] From 561349669a94809bf0b359ba9f80c9a566bcbc08 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Wed, 22 Jun 2016 12:40:48 +1000 Subject: [PATCH 22/33] Addresses several warnings emitted on OS X by removing unused imports and allowing non_upper_case_globals in cocoa event conversion function. --- src/api/cocoa/helpers.rs | 1 - src/api/cocoa/mod.rs | 6 +----- src/window.rs | 3 --- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/api/cocoa/helpers.rs b/src/api/cocoa/helpers.rs index 7fd75710..7738e541 100644 --- a/src/api/cocoa/helpers.rs +++ b/src/api/cocoa/helpers.rs @@ -5,7 +5,6 @@ use GlProfile; use GlRequest; use PixelFormatRequirements; use ReleaseBehavior; -use cocoa::foundation::NSAutoreleasePool; use cocoa::appkit::*; pub fn build_nsattributes(pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&T>) diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index 79f2b71c..6a3996ea 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -7,11 +7,8 @@ use libc; use ContextError; use GlAttributes; use GlContext; -use GlProfile; -use GlRequest; use PixelFormat; use PixelFormatRequirements; -use ReleaseBehavior; use Robustness; use WindowAttributes; use native_monitor::NativeMonitorId; @@ -40,7 +37,6 @@ use std::collections::VecDeque; use std::str::FromStr; use std::str::from_utf8; use std::sync::Mutex; -use std::ascii::AsciiExt; use std::ops::Deref; use events::ElementState::{Pressed, Released}; @@ -825,7 +821,7 @@ impl Clone for IdRef { } } -#[allow(non_snake_case)] +#[allow(non_snake_case, non_upper_case_globals)] unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { if nsevent == nil { return None; } diff --git a/src/window.rs b/src/window.rs index 4cac1ce0..c060fed1 100644 --- a/src/window.rs +++ b/src/window.rs @@ -6,16 +6,13 @@ use ContextError; use CreationError; use CursorState; use Event; -use GlAttributes; use GlContext; use GlProfile; use GlRequest; use MouseCursor; use PixelFormat; -use PixelFormatRequirements; use Robustness; use Window; -use WindowAttributes; use WindowBuilder; use native_monitor::NativeMonitorId; From c2537d81e81b72750113a5ba426315ceb6785095 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Wed, 22 Jun 2016 12:45:42 +1000 Subject: [PATCH 23/33] Remove unused private fields from cocoa HeadlessContext struct. --- src/api/cocoa/headless.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/api/cocoa/headless.rs b/src/api/cocoa/headless.rs index 8d89e404..0a80698a 100644 --- a/src/api/cocoa/headless.rs +++ b/src/api/cocoa/headless.rs @@ -17,8 +17,6 @@ use api::cocoa::helpers; pub struct PlatformSpecificHeadlessBuilderAttributes; pub struct HeadlessContext { - width: u32, - height: u32, context: id, } @@ -44,8 +42,6 @@ impl HeadlessContext { }; let headless = HeadlessContext { - width: width, - height: height, context: context, }; From 9a6b6b3f35dd1e41e7ff55e48916520cfa0d82a8 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Wed, 22 Jun 2016 13:32:36 +1000 Subject: [PATCH 24/33] Remove imports of enum variants in favour of using the type name paths. --- src/api/cocoa/mod.rs | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index 79f2b71c..47a26530 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -43,9 +43,7 @@ use std::sync::Mutex; use std::ascii::AsciiExt; use std::ops::Deref; -use events::ElementState::{Pressed, Released}; -use events::Event::{Awakened, MouseInput, MouseMoved, ReceivedCharacter, KeyboardInput}; -use events::Event::{MouseWheel, Closed, Focused, TouchpadPressure}; +use events::ElementState; use events::{self, MouseButton, TouchPhase}; pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor}; @@ -87,7 +85,7 @@ impl WindowDelegate { unsafe { let state: *mut c_void = *this.get_ivar("glutinState"); let state = state as *mut DelegateState; - (*state).pending_events.lock().unwrap().push_back(Closed); + (*state).pending_events.lock().unwrap().push_back(Event::Closed); } YES } @@ -115,7 +113,7 @@ impl WindowDelegate { let state: *mut c_void = *this.get_ivar("glutinState"); let state = state as *mut DelegateState; - (*state).pending_events.lock().unwrap().push_back(Focused(true)); + (*state).pending_events.lock().unwrap().push_back(Event::Focused(true)); } } @@ -123,7 +121,7 @@ impl WindowDelegate { unsafe { let state: *mut c_void = *this.get_ivar("glutinState"); let state = state as *mut DelegateState; - (*state).pending_events.lock().unwrap().push_back(Focused(false)); + (*state).pending_events.lock().unwrap().push_back(Event::Focused(false)); } } @@ -270,7 +268,7 @@ impl<'a> Iterator for WaitEventsIterator<'a> { } if event.is_none() { - return Some(Awakened); + return Some(Event::Awakened); } else { return event; } @@ -623,9 +621,9 @@ impl Window { unsafe fn modifier_event(event: id, keymask: NSEventModifierFlags, key: events::VirtualKeyCode, key_pressed: bool) -> Option { if !key_pressed && NSEvent::modifierFlags(event).contains(keymask) { - return Some(KeyboardInput(Pressed, NSEvent::keyCode(event) as u8, Some(key))); + return Some(Event::KeyboardInput(ElementState::Pressed, NSEvent::keyCode(event) as u8, Some(key))); } else if key_pressed && !NSEvent::modifierFlags(event).contains(keymask) { - return Some(KeyboardInput(Released, NSEvent::keyCode(event) as u8, Some(key))); + return Some(Event::KeyboardInput(ElementState::Released, NSEvent::keyCode(event) as u8, Some(key))); } return None; @@ -833,10 +831,10 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { NSApp().sendEvent_(if let NSKeyDown = event_type { nil } else { nsevent }); match event_type { - NSLeftMouseDown => { Some(MouseInput(Pressed, MouseButton::Left)) }, - NSLeftMouseUp => { Some(MouseInput(Released, MouseButton::Left)) }, - NSRightMouseDown => { Some(MouseInput(Pressed, MouseButton::Right)) }, - NSRightMouseUp => { Some(MouseInput(Released, MouseButton::Right)) }, + NSLeftMouseDown => { Some(Event::MouseInput(ElementState::Pressed, MouseButton::Left)) }, + NSLeftMouseUp => { Some(Event::MouseInput(ElementState::Released, MouseButton::Left)) }, + NSRightMouseDown => { Some(Event::MouseInput(ElementState::Pressed, MouseButton::Right)) }, + NSRightMouseUp => { Some(Event::MouseInput(ElementState::Released, MouseButton::Right)) }, NSMouseMoved | NSLeftMouseDragged | NSOtherMouseDragged | @@ -852,19 +850,19 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { let view_rect = NSView::frame(*window.view); let scale_factor = window.hidpi_factor(); - Some(MouseMoved((scale_factor * view_point.x as f32) as i32, - (scale_factor * (view_rect.size.height - view_point.y) as f32) as i32)) + Some(Event::MouseMoved((scale_factor * view_point.x as f32) as i32, + (scale_factor * (view_rect.size.height - view_point.y) as f32) as i32)) }, NSKeyDown => { let mut events = VecDeque::new(); let received_c_str = nsevent.characters().UTF8String(); let received_str = CStr::from_ptr(received_c_str); for received_char in from_utf8(received_str.to_bytes()).unwrap().chars() { - events.push_back(ReceivedCharacter(received_char)); + events.push_back(Event::ReceivedCharacter(received_char)); } let vkey = event::vkeycode_to_element(NSEvent::keyCode(nsevent)); - events.push_back(KeyboardInput(Pressed, NSEvent::keyCode(nsevent) as u8, vkey)); + events.push_back(Event::KeyboardInput(ElementState::Pressed, NSEvent::keyCode(nsevent) as u8, vkey)); let event = events.pop_front(); window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter()); event @@ -872,7 +870,7 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { NSKeyUp => { let vkey = event::vkeycode_to_element(NSEvent::keyCode(nsevent)); - Some(KeyboardInput(Released, NSEvent::keyCode(nsevent) as u8, vkey)) + Some(Event::KeyboardInput(ElementState::Released, NSEvent::keyCode(nsevent) as u8, vkey)) }, NSFlagsChanged => { let mut events = VecDeque::new(); @@ -915,10 +913,10 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { NSEventPhaseEnded => TouchPhase::Ended, _ => TouchPhase::Moved, }; - Some(MouseWheel(delta, phase)) + Some(Event::MouseWheel(delta, phase)) }, NSEventTypePressure => { - Some(TouchpadPressure(nsevent.pressure(), nsevent.stage())) + Some(Event::TouchpadPressure(nsevent.pressure(), nsevent.stage())) }, _ => { None }, } From cbb734b5a1797726444f09231033725022c19b56 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Wed, 22 Jun 2016 13:14:47 +1000 Subject: [PATCH 25/33] Remove unnecessary global imports in favour of explicitly importing traits and using namespacing for constants, types and functions. --- src/api/cocoa/mod.rs | 119 ++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index a64f70b8..c46d2ad6 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -22,9 +22,7 @@ use cgl::{CGLEnable, kCGLCECrashOnRemovedFunctions, CGLSetParameter, kCGLCPSurfa use cocoa::base::{id, nil}; use cocoa::foundation::{NSAutoreleasePool, NSDate, NSDefaultRunLoopMode, NSPoint, NSRect, NSSize, NSString, NSUInteger}; -use cocoa::appkit; -use cocoa::appkit::*; -use cocoa::appkit::NSEventSubtype::*; +use cocoa::appkit::{self, NSApplication, NSEvent, NSOpenGLContext, NSOpenGLPixelFormat, NSView, NSWindow}; use core_foundation::base::TCFType; use core_foundation::string::CFString; @@ -200,9 +198,9 @@ impl WindowProxy { let pool = NSAutoreleasePool::new(nil); let event = NSEvent::otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_( - nil, NSApplicationDefined, NSPoint::new(0.0, 0.0), NSEventModifierFlags::empty(), - 0.0, 0, nil, NSApplicationActivatedEventType, 0, 0); - NSApp().postEvent_atStart_(event, NO); + nil, appkit::NSApplicationDefined, NSPoint::new(0.0, 0.0), appkit::NSEventModifierFlags::empty(), + 0.0, 0, nil, appkit::NSEventSubtype::NSApplicationActivatedEventType, 0, 0); + appkit::NSApp().postEvent_atStart_(event, NO); pool.drain(); } } @@ -224,8 +222,8 @@ impl<'a> Iterator for PollEventsIterator<'a> { unsafe { let pool = NSAutoreleasePool::new(nil); - let nsevent = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_( - NSAnyEventMask.bits() | NSEventMaskPressure.bits(), + let nsevent = appkit::NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_( + appkit::NSAnyEventMask.bits() | appkit::NSEventMaskPressure.bits(), NSDate::distantPast(nil), NSDefaultRunLoopMode, YES); @@ -253,8 +251,8 @@ impl<'a> Iterator for WaitEventsIterator<'a> { unsafe { let pool = NSAutoreleasePool::new(nil); - let nsevent = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_( - NSAnyEventMask.bits() | NSEventMaskPressure.bits(), + let nsevent = appkit::NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_( + appkit::NSAnyEventMask.bits() | appkit::NSEventMaskPressure.bits(), NSDate::distantFuture(nil), NSDefaultRunLoopMode, YES); @@ -359,7 +357,7 @@ impl Window { fn create_app(activation_policy: ActivationPolicy) -> Option { unsafe { - let app = NSApp(); + let app = appkit::NSApp(); if app == nil { None } else { @@ -379,13 +377,13 @@ impl Window { _ => panic!("OS X monitors should always have a numeric native ID") }; let matching_screen = { - let screens = NSScreen::screens(nil); + let screens = appkit::NSScreen::screens(nil); let count: NSUInteger = msg_send![screens, count]; let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber")); let mut matching_screen: Option = None; for i in 0..count { let screen = msg_send![screens, objectAtIndex:i as NSUInteger]; - let device_description = NSScreen::deviceDescription(screen); + let device_description = appkit::NSScreen::deviceDescription(screen); let value: id = msg_send![device_description, objectForKey:*key]; if value != nil { let screen_number: NSUInteger = msg_send![value, unsignedIntegerValue]; @@ -397,12 +395,12 @@ impl Window { } matching_screen }; - Some(matching_screen.unwrap_or(NSScreen::mainScreen(nil))) + Some(matching_screen.unwrap_or(appkit::NSScreen::mainScreen(nil))) }, None => None }; let frame = match screen { - Some(screen) => NSScreen::frame(screen), + Some(screen) => appkit::NSScreen::frame(screen), None => { let (width, height) = attrs.dimensions.unwrap_or((800, 600)); NSRect::new(NSPoint::new(0., 0.), NSSize::new(width as f64, height as f64)) @@ -411,28 +409,28 @@ impl Window { let masks = if screen.is_some() || attrs.transparent { // Fullscreen or transparent window - NSBorderlessWindowMask as NSUInteger | - NSResizableWindowMask as NSUInteger | - NSTitledWindowMask as NSUInteger + appkit::NSBorderlessWindowMask as NSUInteger | + appkit::NSResizableWindowMask as NSUInteger | + appkit::NSTitledWindowMask as NSUInteger } else if attrs.decorations { // Classic opaque window with titlebar - NSClosableWindowMask as NSUInteger | - NSMiniaturizableWindowMask as NSUInteger | - NSResizableWindowMask as NSUInteger | - NSTitledWindowMask as NSUInteger + appkit::NSClosableWindowMask as NSUInteger | + appkit::NSMiniaturizableWindowMask as NSUInteger | + appkit::NSResizableWindowMask as NSUInteger | + appkit::NSTitledWindowMask as NSUInteger } else { // Opaque window without a titlebar - NSClosableWindowMask as NSUInteger | - NSMiniaturizableWindowMask as NSUInteger | - NSResizableWindowMask as NSUInteger | - NSTitledWindowMask as NSUInteger | - NSFullSizeContentViewWindowMask as NSUInteger + appkit::NSClosableWindowMask as NSUInteger | + appkit::NSMiniaturizableWindowMask as NSUInteger | + appkit::NSResizableWindowMask as NSUInteger | + appkit::NSTitledWindowMask as NSUInteger | + appkit::NSFullSizeContentViewWindowMask as NSUInteger }; let window = IdRef::new(NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_( frame, masks, - NSBackingStoreBuffered, + appkit::NSBackingStoreBuffered, NO, )); window.non_nil().map(|window| { @@ -441,12 +439,12 @@ impl Window { window.setAcceptsMouseMovedEvents_(YES); if !attrs.decorations { - window.setTitleVisibility_(NSWindowTitleVisibility::NSWindowTitleHidden); + window.setTitleVisibility_(appkit::NSWindowTitleVisibility::NSWindowTitleHidden); window.setTitlebarAppearsTransparent_(YES); } if screen.is_some() { - window.setLevel_(NSMainMenuWindowLevel as i64 + 1); + window.setLevel_(appkit::NSMainMenuWindowLevel as i64 + 1); } else { window.center(); @@ -481,7 +479,7 @@ impl Window { if let Some(cxt) = context.non_nil() { let pf = { - let get_attr = |attrib: NSOpenGLPixelFormatAttribute| -> i32 { + let get_attr = |attrib: appkit::NSOpenGLPixelFormatAttribute| -> i32 { let mut value = 0; NSOpenGLPixelFormat::getValues_forAttribute_forVirtualScreen_( @@ -494,15 +492,15 @@ impl Window { }; PixelFormat { - hardware_accelerated: get_attr(NSOpenGLPFAAccelerated) != 0, - color_bits: (get_attr(NSOpenGLPFAColorSize) - get_attr(NSOpenGLPFAAlphaSize)) as u8, - alpha_bits: get_attr(NSOpenGLPFAAlphaSize) as u8, - depth_bits: get_attr(NSOpenGLPFADepthSize) as u8, - stencil_bits: get_attr(NSOpenGLPFAStencilSize) as u8, - stereoscopy: get_attr(NSOpenGLPFAStereo) != 0, - double_buffer: get_attr(NSOpenGLPFADoubleBuffer) != 0, - multisampling: if get_attr(NSOpenGLPFAMultisample) > 0 { - Some(get_attr(NSOpenGLPFASamples) as u16) + hardware_accelerated: get_attr(appkit::NSOpenGLPFAAccelerated) != 0, + color_bits: (get_attr(appkit::NSOpenGLPFAColorSize) - get_attr(appkit::NSOpenGLPFAAlphaSize)) as u8, + alpha_bits: get_attr(appkit::NSOpenGLPFAAlphaSize) as u8, + depth_bits: get_attr(appkit::NSOpenGLPFADepthSize) as u8, + stencil_bits: get_attr(appkit::NSOpenGLPFAStencilSize) as u8, + stereoscopy: get_attr(appkit::NSOpenGLPFAStereo) != 0, + double_buffer: get_attr(appkit::NSOpenGLPFADoubleBuffer) != 0, + multisampling: if get_attr(appkit::NSOpenGLPFAMultisample) > 0 { + Some(get_attr(appkit::NSOpenGLPFASamples) as u16) } else { None }, @@ -512,7 +510,7 @@ impl Window { cxt.setView_(view); let value = if opengl.vsync { 1 } else { 0 }; - cxt.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval); + cxt.setValues_forParameter_(&value, appkit::NSOpenGLContextParameter::NSOpenGLCPSwapInterval); CGLEnable(cxt.CGLContextObj() as *mut _, kCGLCECrashOnRemovedFunctions); @@ -615,7 +613,7 @@ impl Window { } } - unsafe fn modifier_event(event: id, keymask: NSEventModifierFlags, key: events::VirtualKeyCode, key_pressed: bool) -> Option { + unsafe fn modifier_event(event: id, keymask: appkit::NSEventModifierFlags, key: events::VirtualKeyCode, key_pressed: bool) -> Option { if !key_pressed && NSEvent::modifierFlags(event).contains(keymask) { return Some(Event::KeyboardInput(ElementState::Pressed, NSEvent::keyCode(event) as u8, Some(key))); } else if key_pressed && !NSEvent::modifierFlags(event).contains(keymask) { @@ -713,7 +711,10 @@ impl Window { unsafe { // TODO: Check for errors. - let _ = CGWarpMouseCursorPosition(CGPoint { x: cursor_x as CGFloat, y: cursor_y as CGFloat }); + let _ = CGWarpMouseCursorPosition(appkit::CGPoint { + x: cursor_x as appkit::CGFloat, + y: cursor_y as appkit::CGFloat, + }); let _ = CGAssociateMouseAndMouseCursorPosition(true); } @@ -824,17 +825,17 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { if nsevent == nil { return None; } let event_type = nsevent.eventType(); - NSApp().sendEvent_(if let NSKeyDown = event_type { nil } else { nsevent }); + appkit::NSApp().sendEvent_(if let appkit::NSKeyDown = event_type { nil } else { nsevent }); match event_type { - NSLeftMouseDown => { Some(Event::MouseInput(ElementState::Pressed, MouseButton::Left)) }, - NSLeftMouseUp => { Some(Event::MouseInput(ElementState::Released, MouseButton::Left)) }, - NSRightMouseDown => { Some(Event::MouseInput(ElementState::Pressed, MouseButton::Right)) }, - NSRightMouseUp => { Some(Event::MouseInput(ElementState::Released, MouseButton::Right)) }, - NSMouseMoved | - NSLeftMouseDragged | - NSOtherMouseDragged | - NSRightMouseDragged => { + appkit::NSLeftMouseDown => { Some(Event::MouseInput(ElementState::Pressed, MouseButton::Left)) }, + appkit::NSLeftMouseUp => { Some(Event::MouseInput(ElementState::Released, MouseButton::Left)) }, + appkit::NSRightMouseDown => { Some(Event::MouseInput(ElementState::Pressed, MouseButton::Right)) }, + appkit::NSRightMouseUp => { Some(Event::MouseInput(ElementState::Released, MouseButton::Right)) }, + appkit::NSMouseMoved | + appkit::NSLeftMouseDragged | + appkit::NSOtherMouseDragged | + appkit::NSRightMouseDragged => { let window_point = nsevent.locationInWindow(); let cWindow: id = msg_send![nsevent, window]; let view_point = if cWindow == nil { @@ -849,7 +850,7 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { Some(Event::MouseMoved((scale_factor * view_point.x as f32) as i32, (scale_factor * (view_rect.size.height - view_point.y) as f32) as i32)) }, - NSKeyDown => { + appkit::NSKeyDown => { let mut events = VecDeque::new(); let received_c_str = nsevent.characters().UTF8String(); let received_str = CStr::from_ptr(received_c_str); @@ -863,12 +864,12 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter()); event }, - NSKeyUp => { + appkit::NSKeyUp => { let vkey = event::vkeycode_to_element(NSEvent::keyCode(nsevent)); Some(Event::KeyboardInput(ElementState::Released, NSEvent::keyCode(nsevent) as u8, vkey)) }, - NSFlagsChanged => { + appkit::NSFlagsChanged => { let mut events = VecDeque::new(); let shift_modifier = Window::modifier_event(nsevent, appkit::NSShiftKeyMask, events::VirtualKeyCode::LShift, shift_pressed); if shift_modifier.is_some() { @@ -894,7 +895,7 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter()); event }, - NSScrollWheel => { + appkit::NSScrollWheel => { use events::MouseScrollDelta::{LineDelta, PixelDelta}; let scale_factor = window.hidpi_factor(); let delta = if nsevent.hasPreciseScrollingDeltas() == YES { @@ -905,13 +906,13 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option { scale_factor * nsevent.scrollingDeltaY() as f32) }; let phase = match nsevent.phase() { - NSEventPhaseMayBegin | NSEventPhaseBegan => TouchPhase::Started, - NSEventPhaseEnded => TouchPhase::Ended, + appkit::NSEventPhaseMayBegin | appkit::NSEventPhaseBegan => TouchPhase::Started, + appkit::NSEventPhaseEnded => TouchPhase::Ended, _ => TouchPhase::Moved, }; Some(Event::MouseWheel(delta, phase)) }, - NSEventTypePressure => { + appkit::NSEventTypePressure => { Some(Event::TouchpadPressure(nsevent.pressure(), nsevent.stage())) }, _ => { None }, From 8076255ba89ee2cbcf6034122c3cb464fbd16ddf Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Sun, 26 Jun 2016 11:44:27 +1000 Subject: [PATCH 26/33] Make sure the window does not set itself to autorelease upon closing. --- src/api/cocoa/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs index c46d2ad6..d64bf499 100644 --- a/src/api/cocoa/mod.rs +++ b/src/api/cocoa/mod.rs @@ -435,6 +435,7 @@ impl Window { )); window.non_nil().map(|window| { let title = IdRef::new(NSString::alloc(nil).init_str(&attrs.title)); + window.setReleasedWhenClosed_(NO); window.setTitle_(*title); window.setAcceptsMouseMovedEvents_(YES); From f6ead48378ca383c4af37a9e2d98e8e3fbadee40 Mon Sep 17 00:00:00 2001 From: mraof Date: Wed, 29 Jun 2016 23:28:03 -0400 Subject: [PATCH 27/33] owner_events is now true when grabbing the pointer --- 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 dc7fa62b..8a96ab2f 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -995,7 +995,7 @@ impl Window { Grab => { unsafe { match (self.x.display.xlib.XGrabPointer)( - self.x.display.display, self.x.window, ffi::False, + self.x.display.display, self.x.window, ffi::True, (ffi::ButtonPressMask | ffi::ButtonReleaseMask | ffi::EnterWindowMask | ffi::LeaveWindowMask | ffi::PointerMotionMask | ffi::PointerMotionHintMask | ffi::Button1MotionMask | ffi::Button2MotionMask | ffi::Button3MotionMask | From 952ca7cfed96f2aef4b2207d61de1978bd2c725f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jul 2016 16:20:18 -0700 Subject: [PATCH 28/33] x11: handle X11's multi-key, a.k.a compose key. --- src/api/x11/events.rs | 2 +- src/events.rs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/api/x11/events.rs b/src/api/x11/events.rs index 1c6668c3..4754b1dc 100644 --- a/src/api/x11/events.rs +++ b/src/api/x11/events.rs @@ -14,7 +14,7 @@ pub fn keycode_to_element(scancode: libc::c_uint) -> Option { //ffi::XK_Sys_Req => events::VirtualKeyCode::Sys_req, ffi::XK_Escape => events::VirtualKeyCode::Escape, ffi::XK_Delete => events::VirtualKeyCode::Delete, - //ffi::XK_Multi_key => events::VirtualKeyCode::Multi_key, + ffi::XK_Multi_key => events::VirtualKeyCode::Compose, //ffi::XK_Kanji => events::VirtualKeyCode::Kanji, //ffi::XK_Muhenkan => events::VirtualKeyCode::Muhenkan, //ffi::XK_Henkan_Mode => events::VirtualKeyCode::Henkan_mode, diff --git a/src/events.rs b/src/events.rs index d13a0bfe..7186256c 100644 --- a/src/events.rs +++ b/src/events.rs @@ -220,6 +220,9 @@ pub enum VirtualKeyCode { /// The space bar. Space, + /// The "Compose" key on Linux. + Compose, + Numlock, Numpad0, Numpad1, From 5ce48523cded277b15d8e946865c9dbf5100cc08 Mon Sep 17 00:00:00 2001 From: Victor Koenders Date: Wed, 17 Aug 2016 20:42:45 +0200 Subject: [PATCH 29/33] Added a couple more PartialEq's --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a10957d1..b3623cfc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -329,7 +329,7 @@ pub enum ReleaseBehavior { Flush, } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub enum MouseCursor { /// The platform-dependent default cursor. Default, @@ -386,7 +386,7 @@ pub enum MouseCursor { } /// Describes how glutin handles the cursor. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] pub enum CursorState { /// Normal cursor behavior. Normal, From 1eb2052bcf6c570074947864f2489ed7ca1585f2 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 17 Aug 2016 10:57:34 +1000 Subject: [PATCH 30/33] Add support to Linux headless implementation for specifying OpenGL version. This allows creation of GL3+ headless OSMesa contexts on Linux. --- src/api/osmesa/mod.rs | 47 +++++++++++++++++++++++++++++++++++++++---- src/headless.rs | 10 ++++++++- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/api/osmesa/mod.rs b/src/api/osmesa/mod.rs index f66dce54..50d96c0d 100644 --- a/src/api/osmesa/mod.rs +++ b/src/api/osmesa/mod.rs @@ -7,6 +7,8 @@ use ContextError; use CreationError; use GlAttributes; use GlContext; +use GlProfile; +use GlRequest; use PixelFormat; use PixelFormatRequirements; use Robustness; @@ -34,7 +36,7 @@ impl From for OsMesaCreationError { } impl OsMesaContext { - pub fn new(dimensions: (u32, u32), pf_reqs: &PixelFormatRequirements, + pub fn new(dimensions: (u32, u32), _pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&OsMesaContext>) -> Result { if let Err(_) = osmesa_sys::OsMesa::try_loading() { @@ -51,7 +53,44 @@ impl OsMesaContext { } // TODO: use `pf_reqs` for the format - // TODO: check OpenGL version and return `OpenGlVersionNotSupported` if necessary + + let mut attribs = Vec::new(); + + if let Some(profile) = opengl.profile { + attribs.push(osmesa_sys::OSMESA_PROFILE); + + match profile { + GlProfile::Compatibility => { + attribs.push(osmesa_sys::OSMESA_COMPAT_PROFILE); + } + GlProfile::Core => { + attribs.push(osmesa_sys::OSMESA_CORE_PROFILE); + } + } + } + + match opengl.version { + GlRequest::Latest => {}, + GlRequest::Specific(Api::OpenGl, (major, minor)) => { + attribs.push(osmesa_sys::OSMESA_CONTEXT_MAJOR_VERSION); + attribs.push(major as libc::c_int); + attribs.push(osmesa_sys::OSMESA_CONTEXT_MINOR_VERSION); + attribs.push(minor as libc::c_int); + }, + GlRequest::Specific(Api::OpenGlEs, _) => { + return Err(OsMesaCreationError::NotSupported); + }, + GlRequest::Specific(_, _) => return Err(OsMesaCreationError::NotSupported), + GlRequest::GlThenGles { opengl_version: (major, minor), .. } => { + attribs.push(osmesa_sys::OSMESA_CONTEXT_MAJOR_VERSION); + attribs.push(major as libc::c_int); + attribs.push(osmesa_sys::OSMESA_CONTEXT_MINOR_VERSION); + attribs.push(minor as libc::c_int); + }, + } + + // attribs array must be NULL terminated. + attribs.push(0); Ok(OsMesaContext { width: dimensions.0, @@ -59,9 +98,9 @@ impl OsMesaContext { buffer: ::std::iter::repeat(unsafe { mem::uninitialized() }) .take((dimensions.0 * dimensions.1) as usize).collect(), context: unsafe { - let ctxt = osmesa_sys::OSMesaCreateContext(0x1908, ptr::null_mut()); + let ctxt = osmesa_sys::OSMesaCreateContextAttribs(attribs.as_ptr(), ptr::null_mut()); if ctxt.is_null() { - return Err(CreationError::OsError("OSMesaCreateContext failed".to_string()).into()); + return Err(CreationError::OsError("OSMesaCreateContextAttribs failed".to_string()).into()); } ctxt } diff --git a/src/headless.rs b/src/headless.rs index 31a9f5e4..d9661a63 100644 --- a/src/headless.rs +++ b/src/headless.rs @@ -2,6 +2,7 @@ use Api; use ContextError; use CreationError; use GlAttributes; +use GlProfile; use GlRequest; use GlContext; use PixelFormat; @@ -45,6 +46,13 @@ impl<'a> HeadlessRendererBuilder<'a> { self } + /// Sets the desired OpenGL context profile. + #[inline] + pub fn with_gl_profile(mut self, profile: GlProfile) -> HeadlessRendererBuilder<'a> { + self.opengl.profile = Some(profile); + self + } + /// Sets the *debug* flag for the OpenGL context. /// /// The default value for this flag is `cfg!(ndebug)`, which means that it's enabled @@ -95,7 +103,7 @@ impl HeadlessContext { pub unsafe fn make_current(&self) -> Result<(), ContextError> { self.context.make_current() } - + /// Returns true if this context is the current one in this thread. #[inline] pub fn is_current(&self) -> bool { From 6089fa8c2ce8befce7a68ec0cfcd562b6f7b0407 Mon Sep 17 00:00:00 2001 From: Andrey Lesnikov Date: Mon, 5 Sep 2016 22:10:15 +0300 Subject: [PATCH 31/33] docs.rs --- .travis.yml | 9 --------- Cargo.toml | 2 +- README.md | 4 +++- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index d9ff4962..93c5958c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ addons: env: global: - - secure: "FfubMXYXu2e7chvdfKBkc+aKPkvoBOb5Idg0KCYuD++qPFIBYg6pUE8H8WvU+V7RsEBu5vshhn3dzjkKs+LXIdo5PQUMZutAgy83g5SGxRn8Ra79GjBVBs6+XOEhFun/+7fGj2Ly/AK6BTDpqyYAhAUS7jIaF6/+JWNwPwEYfdQ=" - secure: "kVjHgK+6ivT5tUleNH/m6+69tPf8gkPNSPLsnXrkMJaIeXSnnKKQegP1O0UCThYAUbbwrUGlrKJUngDxkD8jSANhzAULX9t1iXho41InzYBEErTanXBYF8WO1rK1keKjLwiYw4KuvbiBoSeKabzQRwv0kMttxY57+hKVROr5dSg=" script: @@ -24,14 +23,6 @@ os: - osx after_success: - - | - [ $TRAVIS_BRANCH = master ] && - [ $TRAVIS_PULL_REQUEST = false ] && - cargo doc && - echo '' > target/doc/index.html && - sudo pip install ghp-import && - ghp-import -n target/doc && - git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages - | [ $TRAVIS_BRANCH = master ] && [ $TRAVIS_PULL_REQUEST = false ] && diff --git a/Cargo.toml b/Cargo.toml index a2738804..67cd7c6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ keywords = ["windowing", "opengl"] license = "Apache-2.0" readme = "README.md" repository = "https://github.com/tomaka/glutin" -documentation = "https://tomaka.github.io/glutin/" +documentation = "https://docs.rs/glutin" build = "build.rs" [dependencies] diff --git a/README.md b/README.md index ca079cbb..02d647ca 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ [![](http://meritbadge.herokuapp.com/glutin)](https://crates.io/crates/glutin) +[![Docs.rs](https://docs.rs/glutin/badge.svg)](https://docs.rs/glutin) + Alternative to GLFW in pure Rust. [![Build Status](https://travis-ci.org/tomaka/glutin.png?branch=master)](https://travis-ci.org/tomaka/glutin) @@ -13,7 +15,7 @@ Alternative to GLFW in pure Rust. glutin = "*" ``` -## [Documentation](http://tomaka.github.io/glutin/) +## [Documentation](https://docs.io/glutin) ## Try it! From 74d5ae3e8642ec0e306e17e51418e91f47761ebf Mon Sep 17 00:00:00 2001 From: Andrey Lesnikov Date: Tue, 6 Sep 2016 09:39:31 +0300 Subject: [PATCH 32/33] README.rst: docs.io -> docs.rs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 02d647ca..546a187f 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Alternative to GLFW in pure Rust. glutin = "*" ``` -## [Documentation](https://docs.io/glutin) +## [Documentation](https://docs.rs/glutin) ## Try it! From 2c0ba478736aa46d868e8b22637a0e36dc7503b7 Mon Sep 17 00:00:00 2001 From: Andrey Lesnikov Date: Tue, 6 Sep 2016 09:46:31 +0300 Subject: [PATCH 33/33] travis: Enabled deps cache --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 93c5958c..2dadcb66 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ rust: - nightly - stable +cache: cargo + addons: apt: packages: