mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 05:21:31 +11:00
Merge pull request #227 from aepsil0n/grab-cursor
Implement grabbing of the mouse pointer for X11
This commit is contained in:
commit
d6ebaaaf5c
50
examples/grabbing.rs
Normal file
50
examples/grabbing.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
#[cfg(target_os = "android")]
|
||||
#[macro_use]
|
||||
extern crate android_glue;
|
||||
|
||||
extern crate glutin;
|
||||
|
||||
use glutin::{Event, ElementState};
|
||||
|
||||
mod support;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
android_start!(main);
|
||||
|
||||
#[cfg(not(feature = "window"))]
|
||||
fn main() { println!("This example requires glutin to be compiled with the `window` feature"); }
|
||||
|
||||
#[cfg(feature = "window")]
|
||||
fn main() {
|
||||
|
||||
let window = glutin::Window::new().unwrap();
|
||||
window.set_title("glutin - Cursor grabbing test");
|
||||
unsafe { window.make_current() };
|
||||
|
||||
let context = support::load(&window);
|
||||
let mut grabbed = false;
|
||||
|
||||
while !window.is_closed() {
|
||||
context.draw_frame((0.0, 1.0, 0.0, 1.0));
|
||||
window.swap_buffers();
|
||||
|
||||
for event in window.poll_events() {
|
||||
match event {
|
||||
Event::KeyboardInput(ElementState::Pressed, _, _) => {
|
||||
if grabbed {
|
||||
grabbed = false;
|
||||
window.ungrab_cursor();
|
||||
}
|
||||
else {
|
||||
grabbed = true;
|
||||
window.grab_cursor().ok().expect("could not grab mouse cursor");
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -358,6 +358,10 @@ impl Window {
|
|||
pub fn set_cursor(&self, _: MouseCursor) {
|
||||
}
|
||||
|
||||
pub fn grab_cursor(&self) -> Result<(), String> { Ok(()) }
|
||||
|
||||
pub fn ungrab_cursor(&self) {}
|
||||
|
||||
pub fn hidpi_factor(&self) -> f32 {
|
||||
1.0
|
||||
}
|
||||
|
|
|
@ -255,6 +255,14 @@ impl Window {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn grab_cursor(&self) -> Result<(), String> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn ungrab_cursor(&self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn hidpi_factor(&self) -> f32 {
|
||||
1.0
|
||||
}
|
||||
|
|
|
@ -414,6 +414,22 @@ impl Window {
|
|||
pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
|
||||
self.window.set_cursor_position(x, y)
|
||||
}
|
||||
|
||||
/// Grabs the mouse cursor. The cursor's motion will be confined to this
|
||||
/// window and the window has exclusive access to further events regarding
|
||||
/// the cursor.
|
||||
/// Fails if it is not possible to grab the window for some reason, e.g.
|
||||
/// when another window has already done so.
|
||||
/// Has no effect on Android.
|
||||
pub fn grab_cursor(&self) -> Result<(), String> {
|
||||
self.window.grab_cursor()
|
||||
}
|
||||
|
||||
/// Release a previously grabbed mouse cursor.
|
||||
pub fn ungrab_cursor(&self) {
|
||||
self.window.ungrab_cursor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl gl_common::GlFunctionsSource for Window {
|
||||
|
|
|
@ -42,6 +42,17 @@ pub const Button5: libc::c_uint = 5;
|
|||
pub const InputOutput: libc::c_uint = 1;
|
||||
pub const InputOnly: libc::c_uint = 2;
|
||||
|
||||
pub const CurrentTime: Time = 0;
|
||||
|
||||
pub const GrabModeSync: libc::c_int = 0;
|
||||
pub const GrabModeAsync: libc::c_int = 1;
|
||||
|
||||
pub const GrabSuccess: libc::c_int = 0;
|
||||
pub const AlreadyGrabbed: libc::c_int = 1;
|
||||
pub const GrabInvalidTime: libc::c_int = 2;
|
||||
pub const GrabNotViewable: libc::c_int = 3;
|
||||
pub const GrabFrozen: libc::c_int = 4;
|
||||
|
||||
pub const CWBackPixmap: libc::c_ulong = (1<<0);
|
||||
pub const CWBackPixel: libc::c_ulong = (1<<1);
|
||||
pub const CWBorderPixmap: libc::c_ulong = (1<<2);
|
||||
|
@ -1470,6 +1481,10 @@ extern "C" {
|
|||
|
||||
pub fn XcursorLibraryLoadCursor(dpy: *mut Display, name: *const libc::c_char) -> Cursor;
|
||||
pub fn XDefineCursor(dby: *mut Display, w: Window, cursor: Cursor);
|
||||
pub fn XGrabPointer(dpy: *mut Display, w: Window, owner_events: bool, event_mask: libc::c_long,
|
||||
pointer_mode: libc::c_int, keyboard_mode: libc::c_int, confine_to: Window, cursor: Cursor,
|
||||
time: Time) -> libc::c_int;
|
||||
pub fn XUngrabPointer(dpy: *mut Display, time: Time);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -782,6 +782,33 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn grab_cursor(&self) -> Result<(), String> {
|
||||
unsafe {
|
||||
match ffi::XGrabPointer(
|
||||
self.x.display, self.x.window, false,
|
||||
ffi::ButtonPressMask | ffi::ButtonReleaseMask | ffi::EnterWindowMask |
|
||||
ffi::LeaveWindowMask | ffi::PointerMotionMask | ffi::PointerMotionHintMask |
|
||||
ffi::Button1MotionMask | ffi::Button2MotionMask | ffi::Button3MotionMask |
|
||||
ffi::Button4MotionMask | ffi::Button5MotionMask | ffi::ButtonMotionMask |
|
||||
ffi::KeymapStateMask,
|
||||
ffi::GrabModeAsync, ffi::GrabModeAsync,
|
||||
self.x.window, 0, ffi::CurrentTime
|
||||
) {
|
||||
ffi::GrabSuccess => Ok(()),
|
||||
ffi::AlreadyGrabbed | ffi::GrabInvalidTime |
|
||||
ffi::GrabNotViewable | ffi::GrabFrozen
|
||||
=> Err("cursor could not be grabbed".to_string()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ungrab_cursor(&self) {
|
||||
unsafe {
|
||||
ffi::XUngrabPointer(self.x.display, ffi::CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hidpi_factor(&self) -> f32 {
|
||||
1.0
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue