1
0
Fork 0

Run cargo fmt on source files (#106)

* Run cargo fmt on source files

* Update with rustfmt.toml

* Change rustfmt configuration and run it again
This commit is contained in:
Pedro Tacla Yamada 2021-11-10 17:57:54 +11:00 committed by GitHub
parent 9fbfe18f9a
commit 2a894c6bc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 227 additions and 501 deletions

View file

@ -1,2 +1,3 @@
fn_args_layout = "Compressed" fn_args_layout = "Compressed"
use_small_heuristics = "Max"
use_field_init_shorthand = true use_field_init_shorthand = true

View file

@ -1,12 +1,12 @@
use std::time::Duration; use std::time::Duration;
use rtrb::{RingBuffer, Consumer}; use rtrb::{Consumer, RingBuffer};
use baseview::{Event, EventStatus, Window, WindowHandler, WindowScalePolicy}; use baseview::{Event, EventStatus, Window, WindowHandler, WindowScalePolicy};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Message { enum Message {
Hello Hello,
} }
struct OpenWindowExample { struct OpenWindowExample {
@ -40,18 +40,13 @@ fn main() {
let (mut tx, rx) = RingBuffer::new(128).split(); let (mut tx, rx) = RingBuffer::new(128).split();
::std::thread::spawn(move || { ::std::thread::spawn(move || loop {
loop {
::std::thread::sleep(Duration::from_secs(5)); ::std::thread::sleep(Duration::from_secs(5));
if let Err(_) = tx.push(Message::Hello) { if let Err(_) = tx.push(Message::Hello) {
println!("Failed sending message"); println!("Failed sending message");
} }
}
}); });
Window::open_blocking( Window::open_blocking(window_open_options, |_| OpenWindowExample { rx });
window_open_options,
|_| OpenWindowExample { rx }
);
} }

View file

@ -1,7 +1,6 @@
use keyboard_types::KeyboardEvent; use keyboard_types::KeyboardEvent;
use crate::{WindowInfo, Point}; use crate::{Point, WindowInfo};
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum MouseButton { pub enum MouseButton {
@ -83,7 +82,6 @@ pub enum Event {
Window(WindowEvent), Window(WindowEvent),
} }
/// Return value for [WindowHandler::on_event](`crate::WindowHandler::on_event()`), /// Return value for [WindowHandler::on_event](`crate::WindowHandler::on_event()`),
/// indicating whether the event was handled by your window or should be passed /// indicating whether the event was handled by your window or should be passed
/// back to the platform. /// back to the platform.

View file

@ -19,7 +19,6 @@
use keyboard_types::{Code, Location}; use keyboard_types::{Code, Location};
#[cfg(any(target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "linux", target_os = "macos"))]
/// Map key code to location. /// Map key code to location.
/// ///

View file

@ -1,9 +1,9 @@
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
mod win; mod win;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
mod x11; mod x11;
#[cfg(target_os = "macos")]
mod macos;
mod event; mod event;
mod keyboard; mod keyboard;

View file

@ -19,14 +19,13 @@
//! Conversion of platform keyboard event into cross-platform event. //! Conversion of platform keyboard event into cross-platform event.
use cocoa::appkit::{NSEvent, NSEventModifierFlags, NSEventType}; use cocoa::appkit::{NSEvent, NSEventModifierFlags, NSEventType};
use cocoa::foundation::NSString;
use cocoa::base::id; use cocoa::base::id;
use keyboard_types::{Code, KeyState, Key, KeyboardEvent, Modifiers}; use cocoa::foundation::NSString;
use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Modifiers};
use objc::{msg_send, sel, sel_impl}; use objc::{msg_send, sel, sel_impl};
use crate::keyboard::code_to_location; use crate::keyboard::code_to_location;
pub(crate) fn from_nsstring(s: id) -> String { pub(crate) fn from_nsstring(s: id) -> String {
unsafe { unsafe {
let slice = std::slice::from_raw_parts(s.UTF8String() as *const _, s.len()); let slice = std::slice::from_raw_parts(s.UTF8String() as *const _, s.len());
@ -245,7 +244,6 @@ fn code_to_key(code: Code) -> Option<Key> {
}) })
} }
fn is_valid_key(s: &str) -> bool { fn is_valid_key(s: &str) -> bool {
match s.chars().next() { match s.chars().next() {
None => false, None => false,
@ -253,7 +251,6 @@ fn is_valid_key(s: &str) -> bool {
} }
} }
fn is_modifier_code(code: Code) -> bool { fn is_modifier_code(code: Code) -> bool {
matches!( matches!(
code, code,
@ -270,7 +267,6 @@ fn is_modifier_code(code: Code) -> bool {
) )
} }
impl KeyboardState { impl KeyboardState {
pub(crate) fn new() -> KeyboardState { pub(crate) fn new() -> KeyboardState {
let last_mods = NSEventModifierFlags::empty(); let last_mods = NSEventModifierFlags::empty();
@ -329,33 +325,21 @@ impl KeyboardState {
} }
} }
}; };
let event = KeyboardEvent { let event =
code, KeyboardEvent { code, key, location, modifiers, state, is_composing, repeat };
key,
location,
modifiers,
state,
is_composing,
repeat,
};
Some(event) Some(event)
} }
} }
} }
const MODIFIER_MAP: &[(NSEventModifierFlags, Modifiers)] = &[ const MODIFIER_MAP: &[(NSEventModifierFlags, Modifiers)] = &[
(NSEventModifierFlags::NSShiftKeyMask, Modifiers::SHIFT), (NSEventModifierFlags::NSShiftKeyMask, Modifiers::SHIFT),
(NSEventModifierFlags::NSAlternateKeyMask, Modifiers::ALT), (NSEventModifierFlags::NSAlternateKeyMask, Modifiers::ALT),
(NSEventModifierFlags::NSControlKeyMask, Modifiers::CONTROL), (NSEventModifierFlags::NSControlKeyMask, Modifiers::CONTROL),
(NSEventModifierFlags::NSCommandKeyMask, Modifiers::META), (NSEventModifierFlags::NSCommandKeyMask, Modifiers::META),
( (NSEventModifierFlags::NSAlphaShiftKeyMask, Modifiers::CAPS_LOCK),
NSEventModifierFlags::NSAlphaShiftKeyMask,
Modifiers::CAPS_LOCK,
),
]; ];
pub(crate) fn make_modifiers(raw: NSEventModifierFlags) -> Modifiers { pub(crate) fn make_modifiers(raw: NSEventModifierFlags) -> Modifiers {
let mut modifiers = Modifiers::empty(); let mut modifiers = Modifiers::empty();
for &(flags, mods) in MODIFIER_MAP { for &(flags, mods) in MODIFIER_MAP {

View file

@ -1,5 +1,5 @@
mod keyboard; mod keyboard;
mod window;
mod view; mod view;
mod window;
pub use window::*; pub use window::*;

View file

@ -1,7 +1,7 @@
use std::ffi::c_void; use std::ffi::c_void;
use cocoa::appkit::{NSEvent, NSView, NSWindow}; use cocoa::appkit::{NSEvent, NSView, NSWindow};
use cocoa::base::{id, nil, BOOL, YES, NO}; use cocoa::base::{id, nil, BOOL, NO, YES};
use cocoa::foundation::{NSArray, NSPoint, NSRect, NSSize}; use cocoa::foundation::{NSArray, NSPoint, NSRect, NSSize};
use objc::{ use objc::{
@ -13,16 +13,17 @@ use objc::{
}; };
use uuid::Uuid; use uuid::Uuid;
use crate::{Event, EventStatus, MouseButton, MouseEvent, Point, Size, WindowEvent, WindowInfo, WindowOpenOptions};
use crate::MouseEvent::{ButtonPressed, ButtonReleased}; use crate::MouseEvent::{ButtonPressed, ButtonReleased};
use crate::{
Event, EventStatus, MouseButton, MouseEvent, Point, Size, WindowEvent, WindowInfo,
WindowOpenOptions,
};
use super::window::WindowState; use super::window::WindowState;
/// Name of the field used to store the `WindowState` pointer. /// Name of the field used to store the `WindowState` pointer.
pub(super) const BASEVIEW_STATE_IVAR: &str = "baseview_state"; pub(super) const BASEVIEW_STATE_IVAR: &str = "baseview_state";
macro_rules! add_simple_mouse_class_method { macro_rules! add_simple_mouse_class_method {
($class:ident, $sel:ident, $event:expr) => { ($class:ident, $sel:ident, $event:expr) => {
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -41,7 +42,6 @@ macro_rules! add_simple_mouse_class_method {
}; };
} }
macro_rules! add_simple_keyboard_class_method { macro_rules! add_simple_keyboard_class_method {
($class:ident, $sel:ident) => { ($class:ident, $sel:ident) => {
#[allow(non_snake_case)] #[allow(non_snake_case)]
@ -70,25 +70,18 @@ macro_rules! add_simple_keyboard_class_method {
}; };
} }
pub(super) unsafe fn create_view(window_options: &WindowOpenOptions) -> id {
pub(super) unsafe fn create_view(
window_options: &WindowOpenOptions,
) -> id {
let class = create_view_class(); let class = create_view_class();
let view: id = msg_send![class, alloc]; let view: id = msg_send![class, alloc];
let size = window_options.size; let size = window_options.size;
view.initWithFrame_(NSRect::new( view.initWithFrame_(NSRect::new(NSPoint::new(0., 0.), NSSize::new(size.width, size.height)));
NSPoint::new(0., 0.),
NSSize::new(size.width, size.height),
));
view view
} }
unsafe fn create_view_class() -> &'static Class { unsafe fn create_view_class() -> &'static Class {
// Use unique class names so that there are no conflicts between different // Use unique class names so that there are no conflicts between different
// instances. The class is deleted when the view is released. Previously, // instances. The class is deleted when the view is released. Previously,
@ -100,102 +93,47 @@ unsafe fn create_view_class() -> &'static Class {
class.add_method( class.add_method(
sel!(acceptsFirstResponder), sel!(acceptsFirstResponder),
property_yes as extern "C" fn(&Object, Sel) -> BOOL property_yes as extern "C" fn(&Object, Sel) -> BOOL,
);
class.add_method(
sel!(isFlipped),
property_yes as extern "C" fn(&Object, Sel) -> BOOL
); );
class.add_method(sel!(isFlipped), property_yes as extern "C" fn(&Object, Sel) -> BOOL);
class.add_method( class.add_method(
sel!(preservesContentInLiveResize), sel!(preservesContentInLiveResize),
property_no as extern "C" fn(&Object, Sel) -> BOOL property_no as extern "C" fn(&Object, Sel) -> BOOL,
); );
class.add_method( class.add_method(
sel!(acceptsFirstMouse:), sel!(acceptsFirstMouse:),
accepts_first_mouse as extern "C" fn(&Object, Sel, id) -> BOOL accepts_first_mouse as extern "C" fn(&Object, Sel, id) -> BOOL,
); );
class.add_method( class.add_method(sel!(release), release as extern "C" fn(&mut Object, Sel));
sel!(release), class.add_method(sel!(dealloc), dealloc as extern "C" fn(&mut Object, Sel));
release as extern "C" fn(&mut Object, Sel)
);
class.add_method(
sel!(dealloc),
dealloc as extern "C" fn(&mut Object, Sel)
);
class.add_method( class.add_method(
sel!(viewWillMoveToWindow:), sel!(viewWillMoveToWindow:),
view_will_move_to_window as extern "C" fn(&Object, Sel, id) view_will_move_to_window as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(
sel!(updateTrackingAreas:), sel!(updateTrackingAreas:),
update_tracking_areas as extern "C" fn(&Object, Sel, id) update_tracking_areas as extern "C" fn(&Object, Sel, id),
); );
class.add_method( class.add_method(sel!(mouseMoved:), mouse_moved as extern "C" fn(&Object, Sel, id));
sel!(mouseMoved:), class.add_method(sel!(mouseDragged:), mouse_moved as extern "C" fn(&Object, Sel, id));
mouse_moved as extern "C" fn(&Object, Sel, id), class.add_method(sel!(rightMouseDragged:), mouse_moved as extern "C" fn(&Object, Sel, id));
); class.add_method(sel!(otherMouseDragged:), mouse_moved as extern "C" fn(&Object, Sel, id));
class.add_method(
sel!(mouseDragged:),
mouse_moved as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(rightMouseDragged:),
mouse_moved as extern "C" fn(&Object, Sel, id),
);
class.add_method(
sel!(otherMouseDragged:),
mouse_moved as extern "C" fn(&Object, Sel, id),
);
class.add_method( class.add_method(
sel!(viewDidChangeBackingProperties:), sel!(viewDidChangeBackingProperties:),
view_did_change_backing_properties as extern "C" fn(&Object, Sel, id), view_did_change_backing_properties as extern "C" fn(&Object, Sel, id),
); );
add_simple_mouse_class_method!(class, mouseDown, ButtonPressed(MouseButton::Left));
add_simple_mouse_class_method!(class, mouseUp, ButtonReleased(MouseButton::Left));
add_simple_mouse_class_method!( add_simple_mouse_class_method!(class, rightMouseDown, ButtonPressed(MouseButton::Right));
class, add_simple_mouse_class_method!(class, rightMouseUp, ButtonReleased(MouseButton::Right));
mouseDown, add_simple_mouse_class_method!(class, otherMouseDown, ButtonPressed(MouseButton::Middle));
ButtonPressed(MouseButton::Left) add_simple_mouse_class_method!(class, otherMouseUp, ButtonReleased(MouseButton::Middle));
); add_simple_mouse_class_method!(class, mouseEntered, MouseEvent::CursorEntered);
add_simple_mouse_class_method!( add_simple_mouse_class_method!(class, mouseExited, MouseEvent::CursorLeft);
class,
mouseUp,
ButtonReleased(MouseButton::Left)
);
add_simple_mouse_class_method!(
class,
rightMouseDown,
ButtonPressed(MouseButton::Right)
);
add_simple_mouse_class_method!(
class,
rightMouseUp,
ButtonReleased(MouseButton::Right)
);
add_simple_mouse_class_method!(
class,
otherMouseDown,
ButtonPressed(MouseButton::Middle)
);
add_simple_mouse_class_method!(
class,
otherMouseUp,
ButtonReleased(MouseButton::Middle)
);
add_simple_mouse_class_method!(
class,
mouseEntered,
MouseEvent::CursorEntered
);
add_simple_mouse_class_method!(
class,
mouseExited,
MouseEvent::CursorLeft
);
add_simple_keyboard_class_method!(class, keyDown); add_simple_keyboard_class_method!(class, keyDown);
add_simple_keyboard_class_method!(class, keyUp); add_simple_keyboard_class_method!(class, keyUp);
@ -206,32 +144,18 @@ unsafe fn create_view_class() -> &'static Class {
class.register() class.register()
} }
extern "C" fn property_yes(_this: &Object, _sel: Sel) -> BOOL {
extern "C" fn property_yes(
_this: &Object,
_sel: Sel,
) -> BOOL {
YES YES
} }
extern "C" fn property_no(_this: &Object, _sel: Sel) -> BOOL {
extern "C" fn property_no(
_this: &Object,
_sel: Sel,
) -> BOOL {
NO NO
} }
extern "C" fn accepts_first_mouse(_this: &Object, _sel: Sel, _event: id) -> BOOL {
extern "C" fn accepts_first_mouse(
_this: &Object,
_sel: Sel,
_event: id
) -> BOOL {
YES YES
} }
extern "C" fn release(this: &mut Object, _sel: Sel) { extern "C" fn release(this: &mut Object, _sel: Sel) {
// Hack for breaking circular references. We store the value of retainCount // Hack for breaking circular references. We store the value of retainCount
// after build(), and then when retainCount drops back to that value, we // after build(), and then when retainCount drops back to that value, we
@ -250,23 +174,18 @@ extern "C" fn release(this: &mut Object, _sel: Sel) {
let state_ptr: *mut c_void = *this.get_ivar(BASEVIEW_STATE_IVAR); let state_ptr: *mut c_void = *this.get_ivar(BASEVIEW_STATE_IVAR);
if !state_ptr.is_null(){ if !state_ptr.is_null() {
let retain_count_after_build = WindowState::from_field(this) let retain_count_after_build = WindowState::from_field(this).retain_count_after_build;
.retain_count_after_build;
if retain_count <= retain_count_after_build { if retain_count <= retain_count_after_build {
WindowState::from_field(this).remove_timer(); WindowState::from_field(this).remove_timer();
this.set_ivar( this.set_ivar(BASEVIEW_STATE_IVAR, ::std::ptr::null() as *const c_void);
BASEVIEW_STATE_IVAR,
::std::ptr::null() as *const c_void
);
// Drop WindowState // Drop WindowState
Box::from_raw(state_ptr as *mut WindowState); Box::from_raw(state_ptr as *mut WindowState);
} }
} }
} }
unsafe { unsafe {
@ -287,15 +206,12 @@ extern "C" fn dealloc(this: &mut Object, _sel: Sel) {
} }
} }
extern "C" fn view_did_change_backing_properties(this: &Object, _:Sel, _:id) { extern "C" fn view_did_change_backing_properties(this: &Object, _: Sel, _: id) {
unsafe { unsafe {
let ns_window: *mut Object = msg_send![this, window]; let ns_window: *mut Object = msg_send![this, window];
let scale_factor: f64 = if ns_window.is_null() { let scale_factor: f64 =
1.0 if ns_window.is_null() { 1.0 } else { NSWindow::backingScaleFactor(ns_window) as f64 };
} else {
NSWindow::backingScaleFactor(ns_window) as f64
};
let state: &mut WindowState = WindowState::from_field(this); let state: &mut WindowState = WindowState::from_field(this);
@ -303,23 +219,20 @@ extern "C" fn view_did_change_backing_properties(this: &Object, _:Sel, _:id) {
let window_info = WindowInfo::from_logical_size( let window_info = WindowInfo::from_logical_size(
Size::new(bounds.size.width, bounds.size.height), Size::new(bounds.size.width, bounds.size.height),
scale_factor scale_factor,
); );
state.trigger_event( state.trigger_event(Event::Window(WindowEvent::Resized(window_info)));
Event::Window(WindowEvent::Resized(window_info))
);
} }
} }
/// Init/reinit tracking area /// Init/reinit tracking area
/// ///
/// Info: /// Info:
/// https://developer.apple.com/documentation/appkit/nstrackingarea /// https://developer.apple.com/documentation/appkit/nstrackingarea
/// https://developer.apple.com/documentation/appkit/nstrackingarea/options /// https://developer.apple.com/documentation/appkit/nstrackingarea/options
/// https://developer.apple.com/documentation/appkit/nstrackingareaoptions /// https://developer.apple.com/documentation/appkit/nstrackingareaoptions
unsafe fn reinit_tracking_area(this: &Object, tracking_area: *mut Object){ unsafe fn reinit_tracking_area(this: &Object, tracking_area: *mut Object) {
let options: usize = { let options: usize = {
let mouse_entered_and_exited = 0x01; let mouse_entered_and_exited = 0x01;
let tracking_mouse_moved = 0x02; let tracking_mouse_moved = 0x02;
@ -328,9 +241,12 @@ unsafe fn reinit_tracking_area(this: &Object, tracking_area: *mut Object){
let tracking_in_visible_rect = 0x200; let tracking_in_visible_rect = 0x200;
let tracking_enabled_during_mouse_drag = 0x400; let tracking_enabled_during_mouse_drag = 0x400;
mouse_entered_and_exited | tracking_mouse_moved | mouse_entered_and_exited
tracking_cursor_update | tracking_active_in_active_app | | tracking_mouse_moved
tracking_in_visible_rect | tracking_enabled_during_mouse_drag | tracking_cursor_update
| tracking_active_in_active_app
| tracking_in_visible_rect
| tracking_enabled_during_mouse_drag
}; };
let bounds: NSRect = msg_send![this, bounds]; let bounds: NSRect = msg_send![this, bounds];
@ -343,27 +259,20 @@ unsafe fn reinit_tracking_area(this: &Object, tracking_area: *mut Object){
]; ];
} }
extern "C" fn view_will_move_to_window(this: &Object, _self: Sel, new_window: id) {
extern "C" fn view_will_move_to_window(
this: &Object,
_self: Sel,
new_window: id
){
unsafe { unsafe {
let tracking_areas: *mut Object = msg_send![this, trackingAreas]; let tracking_areas: *mut Object = msg_send![this, trackingAreas];
let tracking_area_count = NSArray::count(tracking_areas); let tracking_area_count = NSArray::count(tracking_areas);
let _: () = msg_send![class!(NSEvent), setMouseCoalescingEnabled:NO]; let _: () = msg_send![class!(NSEvent), setMouseCoalescingEnabled: NO];
if new_window == nil { if new_window == nil {
if tracking_area_count != 0 { if tracking_area_count != 0 {
let tracking_area = NSArray::objectAtIndex(tracking_areas, 0); let tracking_area = NSArray::objectAtIndex(tracking_areas, 0);
let _: () = msg_send![this, removeTrackingArea: tracking_area];
let _: () = msg_send![this, removeTrackingArea:tracking_area];
let _: () = msg_send![tracking_area, release]; let _: () = msg_send![tracking_area, release];
} }
} else { } else {
if tracking_area_count == 0 { if tracking_area_count == 0 {
let class = Class::get("NSTrackingArea").unwrap(); let class = Class::get("NSTrackingArea").unwrap();
@ -372,27 +281,22 @@ extern "C" fn view_will_move_to_window(
reinit_tracking_area(this, tracking_area); reinit_tracking_area(this, tracking_area);
let _: () = msg_send![this, addTrackingArea:tracking_area]; let _: () = msg_send![this, addTrackingArea: tracking_area];
} }
let _: () = msg_send![new_window, setAcceptsMouseMovedEvents:YES]; let _: () = msg_send![new_window, setAcceptsMouseMovedEvents: YES];
let _: () = msg_send![new_window, makeFirstResponder:this]; let _: () = msg_send![new_window, makeFirstResponder: this];
} }
} }
unsafe { unsafe {
let superclass = msg_send![this, superclass]; let superclass = msg_send![this, superclass];
let () = msg_send![super(this, superclass), viewWillMoveToWindow:new_window]; let () = msg_send![super(this, superclass), viewWillMoveToWindow: new_window];
} }
} }
extern "C" fn update_tracking_areas(this: &Object, _self: Sel, _: id) {
extern "C" fn update_tracking_areas(
this: &Object,
_self: Sel,
_: id
){
unsafe { unsafe {
let tracking_areas: *mut Object = msg_send![this, trackingAreas]; let tracking_areas: *mut Object = msg_send![this, trackingAreas];
let tracking_area = NSArray::objectAtIndex(tracking_areas, 0); let tracking_area = NSArray::objectAtIndex(tracking_areas, 0);
@ -401,15 +305,8 @@ extern "C" fn update_tracking_areas(
} }
} }
extern "C" fn mouse_moved(this: &Object, _sel: Sel, event: id) {
extern "C" fn mouse_moved( let state: &mut WindowState = unsafe { WindowState::from_field(this) };
this: &Object,
_sel: Sel,
event: id
){
let state: &mut WindowState = unsafe {
WindowState::from_field(this)
};
let point: NSPoint = unsafe { let point: NSPoint = unsafe {
let point = NSEvent::locationInWindow(event); let point = NSEvent::locationInWindow(event);
@ -417,12 +314,7 @@ extern "C" fn mouse_moved(
msg_send![this, convertPoint:point fromView:nil] msg_send![this, convertPoint:point fromView:nil]
}; };
let position = Point { let position = Point { x: point.x, y: point.y };
x: point.x,
y: point.y
};
state.trigger_event( state.trigger_event(Event::Mouse(MouseEvent::CursorMoved { position }));
Event::Mouse(MouseEvent::CursorMoved { position })
);
} }

View file

@ -1,14 +1,13 @@
use std::ffi::c_void; use std::ffi::c_void;
use cocoa::appkit::{ use cocoa::appkit::{
NSApp, NSApplication, NSApplicationActivationPolicyRegular, NSApp, NSApplication, NSApplicationActivationPolicyRegular, NSBackingStoreBuffered, NSWindow,
NSBackingStoreBuffered, NSWindow, NSWindowStyleMask, NSWindowStyleMask,
}; };
use cocoa::base::{id, nil, NO}; use cocoa::base::{id, nil, NO};
use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString}; use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString};
use core_foundation::runloop::{ use core_foundation::runloop::{
CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer, CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer, kCFRunLoopDefaultMode,
kCFRunLoopDefaultMode,
}; };
use keyboard_types::KeyboardEvent; use keyboard_types::KeyboardEvent;
@ -16,14 +15,10 @@ use objc::{msg_send, runtime::Object, sel, sel_impl};
use raw_window_handle::{macos::MacOSHandle, HasRawWindowHandle, RawWindowHandle}; use raw_window_handle::{macos::MacOSHandle, HasRawWindowHandle, RawWindowHandle};
use crate::{ use crate::{Event, EventStatus, WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy};
Event, EventStatus, WindowHandler, WindowOpenOptions, WindowScalePolicy,
WindowInfo,
};
use super::view::{create_view, BASEVIEW_STATE_IVAR};
use super::keyboard::KeyboardState; use super::keyboard::KeyboardState;
use super::view::{create_view, BASEVIEW_STATE_IVAR};
pub struct Window { pub struct Window {
/// Only set if we created the parent window, i.e. we are running in /// Only set if we created the parent window, i.e. we are running in
@ -51,10 +46,7 @@ impl Window {
let ns_view = unsafe { create_view(&options) }; let ns_view = unsafe { create_view(&options) };
let window = Window { let window = Window { ns_window: None, ns_view };
ns_window: None,
ns_view,
};
Self::init(window, build); Self::init(window, build);
@ -76,10 +68,7 @@ impl Window {
let ns_view = unsafe { create_view(&options) }; let ns_view = unsafe { create_view(&options) };
let window = Window { let window = Window { ns_window: None, ns_view };
ns_window: None,
ns_view,
};
let raw_window_handle = window.raw_window_handle(); let raw_window_handle = window.raw_window_handle();
@ -108,9 +97,7 @@ impl Window {
let app = unsafe { NSApp() }; let app = unsafe { NSApp() };
unsafe { unsafe {
app.setActivationPolicy_( app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
NSApplicationActivationPolicyRegular
);
} }
let scaling = match options.scale { let scaling = match options.scale {
@ -118,22 +105,18 @@ impl Window {
WindowScalePolicy::SystemScaleFactor => 1.0, WindowScalePolicy::SystemScaleFactor => 1.0,
}; };
let window_info = WindowInfo::from_logical_size( let window_info = WindowInfo::from_logical_size(options.size, scaling);
options.size,
scaling
);
let rect = NSRect::new( let rect = NSRect::new(
NSPoint::new(0.0, 0.0), NSPoint::new(0.0, 0.0),
NSSize::new( NSSize::new(
window_info.logical_size().width as f64, window_info.logical_size().width as f64,
window_info.logical_size().height as f64 window_info.logical_size().height as f64,
), ),
); );
let ns_window = unsafe { let ns_window = unsafe {
let ns_window = NSWindow::alloc(nil) let ns_window = NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_(
.initWithContentRect_styleMask_backing_defer_(
rect, rect,
NSWindowStyleMask::NSTitledWindowMask, NSWindowStyleMask::NSTitledWindowMask,
NSBackingStoreBuffered, NSBackingStoreBuffered,
@ -141,9 +124,7 @@ impl Window {
); );
ns_window.center(); ns_window.center();
let title = NSString::alloc(nil) let title = NSString::alloc(nil).init_str(&options.title).autorelease();
.init_str(&options.title)
.autorelease();
ns_window.setTitle_(title); ns_window.setTitle_(title);
ns_window.makeKeyAndOrderFront_(nil); ns_window.makeKeyAndOrderFront_(nil);
@ -153,10 +134,7 @@ impl Window {
let ns_view = unsafe { create_view(&options) }; let ns_view = unsafe { create_view(&options) };
let window = Window { let window = Window { ns_window: Some(ns_window), ns_view };
ns_window: Some(ns_window),
ns_view,
};
Self::init(window, build); Self::init(window, build);
@ -170,19 +148,15 @@ impl Window {
} }
} }
fn init<H, B>( fn init<H, B>(mut window: Window, build: B)
mut window: Window, where
build: B H: WindowHandler + 'static,
)
where H: WindowHandler + 'static,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
B: Send + 'static, B: Send + 'static,
{ {
let window_handler = Box::new(build(&mut crate::Window::new(&mut window))); let window_handler = Box::new(build(&mut crate::Window::new(&mut window)));
let retain_count_after_build: usize = unsafe { let retain_count_after_build: usize = unsafe { msg_send![window.ns_view, retainCount] };
msg_send![window.ns_view, retainCount]
};
let window_state_ptr = Box::into_raw(Box::new(WindowState { let window_state_ptr = Box::into_raw(Box::new(WindowState {
window, window,
@ -193,17 +167,14 @@ impl Window {
})); }));
unsafe { unsafe {
(*(*window_state_ptr).window.ns_view).set_ivar( (*(*window_state_ptr).window.ns_view)
BASEVIEW_STATE_IVAR, .set_ivar(BASEVIEW_STATE_IVAR, window_state_ptr as *mut c_void);
window_state_ptr as *mut c_void
);
WindowState::setup_timer(window_state_ptr); WindowState::setup_timer(window_state_ptr);
} }
} }
} }
pub(super) struct WindowState { pub(super) struct WindowState {
window: Window, window: Window,
window_handler: Box<dyn WindowHandler>, window_handler: Box<dyn WindowHandler>,
@ -212,7 +183,6 @@ pub(super) struct WindowState {
pub retain_count_after_build: usize, pub retain_count_after_build: usize,
} }
impl WindowState { impl WindowState {
/// Returns a mutable reference to a WindowState from an Objective-C field /// Returns a mutable reference to a WindowState from an Objective-C field
/// ///
@ -226,32 +196,22 @@ impl WindowState {
} }
pub(super) fn trigger_event(&mut self, event: Event) -> EventStatus { pub(super) fn trigger_event(&mut self, event: Event) -> EventStatus {
self.window_handler self.window_handler.on_event(&mut crate::Window::new(&mut self.window), event)
.on_event(&mut crate::Window::new(&mut self.window), event)
} }
pub(super) fn trigger_frame(&mut self) { pub(super) fn trigger_frame(&mut self) {
self.window_handler self.window_handler.on_frame(&mut crate::Window::new(&mut self.window));
.on_frame(&mut crate::Window::new(&mut self.window));
} }
pub(super) fn process_native_key_event( pub(super) fn process_native_key_event(&mut self, event: *mut Object) -> Option<KeyboardEvent> {
&mut self,
event: *mut Object
) -> Option<KeyboardEvent> {
self.keyboard_state.process_native_event(event) self.keyboard_state.process_native_event(event)
} }
/// Don't call until WindowState pointer is stored in view /// Don't call until WindowState pointer is stored in view
unsafe fn setup_timer(window_state_ptr: *mut WindowState) { unsafe fn setup_timer(window_state_ptr: *mut WindowState) {
extern "C" fn timer_callback( extern "C" fn timer_callback(_: *mut __CFRunLoopTimer, window_state_ptr: *mut c_void) {
_: *mut __CFRunLoopTimer,
window_state_ptr: *mut c_void,
) {
unsafe { unsafe {
let window_state = &mut *( let window_state = &mut *(window_state_ptr as *mut WindowState);
window_state_ptr as *mut WindowState
);
window_state.trigger_frame(); window_state.trigger_frame();
} }
@ -265,17 +225,9 @@ impl WindowState {
copyDescription: None, copyDescription: None,
}; };
let timer = CFRunLoopTimer::new( let timer = CFRunLoopTimer::new(0.0, 0.015, 0, 0, timer_callback, &mut timer_context);
0.0,
0.015,
0,
0,
timer_callback,
&mut timer_context,
);
CFRunLoop::get_current() CFRunLoop::get_current().add_timer(&timer, kCFRunLoopDefaultMode);
.add_timer(&timer, kCFRunLoopDefaultMode);
let window_state = &mut *(window_state_ptr); let window_state = &mut *(window_state_ptr);
@ -285,18 +237,14 @@ impl WindowState {
/// Call when freeing view /// Call when freeing view
pub(super) unsafe fn remove_timer(&mut self) { pub(super) unsafe fn remove_timer(&mut self) {
if let Some(frame_timer) = self.frame_timer.take() { if let Some(frame_timer) = self.frame_timer.take() {
CFRunLoop::get_current() CFRunLoop::get_current().remove_timer(&frame_timer, kCFRunLoopDefaultMode);
.remove_timer(&frame_timer, kCFRunLoopDefaultMode);
} }
} }
} }
unsafe impl HasRawWindowHandle for Window { unsafe impl HasRawWindowHandle for Window {
fn raw_window_handle(&self) -> RawWindowHandle { fn raw_window_handle(&self) -> RawWindowHandle {
let ns_window = self.ns_window.unwrap_or( let ns_window = self.ns_window.unwrap_or(::std::ptr::null_mut()) as *mut c_void;
::std::ptr::null_mut()
) as *mut c_void;
RawWindowHandle::MacOS(MacOSHandle { RawWindowHandle::MacOS(MacOSHandle {
ns_window, ns_window,

View file

@ -23,7 +23,7 @@ use std::convert::TryInto;
use std::mem; use std::mem;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
use keyboard_types::{Code, Key, KeyboardEvent, KeyState, Location, Modifiers}; use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, Modifiers};
use winapi::shared::minwindef::{HKL, INT, LPARAM, UINT, WPARAM}; use winapi::shared::minwindef::{HKL, INT, LPARAM, UINT, WPARAM};
use winapi::shared::ntdef::SHORT; use winapi::shared::ntdef::SHORT;
@ -502,14 +502,8 @@ impl KeyboardState {
let stash_vk = None; let stash_vk = None;
let stash_utf16 = Vec::new(); let stash_utf16 = Vec::new();
let has_altgr = false; let has_altgr = false;
let mut result = KeyboardState { let mut result =
hkl, KeyboardState { hkl, key_vals, dead_keys, has_altgr, stash_vk, stash_utf16 };
key_vals,
dead_keys,
has_altgr,
stash_vk,
stash_utf16,
};
result.load_keyboard_layout(); result.load_keyboard_layout();
result result
} }
@ -548,11 +542,7 @@ impl KeyboardState {
/// a valid `HKL` reference in the `WM_INPUTLANGCHANGE` message. Actual danger /// a valid `HKL` reference in the `WM_INPUTLANGCHANGE` message. Actual danger
/// is likely low, though. /// is likely low, though.
pub(crate) unsafe fn process_message( pub(crate) unsafe fn process_message(
&mut self, &mut self, hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM,
hwnd: HWND,
msg: UINT,
wparam: WPARAM,
lparam: LPARAM,
) -> Option<KeyboardEvent> { ) -> Option<KeyboardEvent> {
match msg { match msg {
WM_KEYDOWN | WM_SYSKEYDOWN => { WM_KEYDOWN | WM_SYSKEYDOWN => {

View file

@ -1,4 +1,4 @@
mod window;
mod keyboard; mod keyboard;
mod window;
pub use window::*; pub use window::*;

View file

@ -3,35 +3,29 @@ use winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM};
use winapi::shared::windef::{HWND, RECT}; use winapi::shared::windef::{HWND, RECT};
use winapi::um::combaseapi::CoCreateGuid; use winapi::um::combaseapi::CoCreateGuid;
use winapi::um::winuser::{ use winapi::um::winuser::{
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DispatchMessageW, AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW,
GetMessageW, GetWindowLongPtrW, PostMessageW, RegisterClassW, SetTimer, GetCapture, GetDpiForWindow, GetMessageW, GetWindowLongPtrW, IsWindow, LoadCursorW,
SetWindowLongPtrW, TranslateMessage, UnregisterClassW, LoadCursorW, PostMessageW, RegisterClassW, ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext,
DestroyWindow, SetProcessDpiAwarenessContext, SetWindowPos, SetTimer, SetWindowLongPtrW, SetWindowPos, TranslateMessage, UnregisterClassW, CS_OWNDC,
GetDpiForWindow, GET_XBUTTON_WPARAM, GWLP_USERDATA, IDC_ARROW, MSG, SWP_NOMOVE, SWP_NOZORDER, WHEEL_DELTA,
CS_OWNDC, GWLP_USERDATA, IDC_ARROW, WM_CHAR, WM_CLOSE, WM_CREATE, WM_DPICHANGED, WM_INPUTLANGCHANGE, WM_KEYDOWN, WM_KEYUP,
MSG, WM_CLOSE, WM_CREATE, WM_MOUSEMOVE, WM_MOUSEWHEEL, WHEEL_DELTA, WM_SHOWWINDOW, WM_TIMER, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL,
WM_NCDESTROY, WNDCLASSW, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WM_NCDESTROY, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SHOWWINDOW, WM_SIZE, WM_SYSCHAR, WM_SYSKEYDOWN,
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE, WM_DPICHANGED, WM_CHAR, WM_SYSCHAR, WM_KEYDOWN, WM_SYSKEYUP, WM_TIMER, WM_XBUTTONDOWN, WM_XBUTTONUP, WNDCLASSW, WS_CAPTION, WS_CHILD,
WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP, WM_INPUTLANGCHANGE, WM_SIZE, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
GET_XBUTTON_WPARAM, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, XBUTTON1, XBUTTON2,
WM_RBUTTONDOWN, WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2,
SetCapture, GetCapture, ReleaseCapture, IsWindow, SWP_NOZORDER, SWP_NOMOVE
}; };
use std::cell::RefCell; use std::cell::RefCell;
use std::ffi::{OsStr, c_void}; use std::ffi::{c_void, OsStr};
use std::os::windows::ffi::OsStrExt; use std::os::windows::ffi::OsStrExt;
use std::ptr::null_mut; use std::ptr::null_mut;
use raw_window_handle::{ use raw_window_handle::{windows::WindowsHandle, HasRawWindowHandle, RawWindowHandle};
windows::WindowsHandle,
HasRawWindowHandle,
RawWindowHandle
};
use crate::{ use crate::{
Event, MouseButton, MouseEvent, ScrollDelta, WindowEvent, Event, MouseButton, MouseEvent, PhyPoint, PhySize, ScrollDelta, WindowEvent, WindowHandler,
WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy, PhyPoint, PhySize WindowInfo, WindowOpenOptions, WindowScalePolicy,
}; };
use super::keyboard::KeyboardState; use super::keyboard::KeyboardState;
@ -83,9 +77,7 @@ unsafe extern "system" fn wnd_proc(
window_state.handler.on_event( window_state.handler.on_event(
&mut window, &mut window,
Event::Mouse(MouseEvent::CursorMoved { Event::Mouse(MouseEvent::CursorMoved { position: logical_pos }),
position: logical_pos,
}),
); );
return 0; return 0;
} }
@ -105,9 +97,8 @@ unsafe extern "system" fn wnd_proc(
); );
return 0; return 0;
} }
WM_LBUTTONDOWN | WM_LBUTTONUP | WM_MBUTTONDOWN | WM_MBUTTONUP | WM_LBUTTONDOWN | WM_LBUTTONUP | WM_MBUTTONDOWN | WM_MBUTTONUP | WM_RBUTTONDOWN
WM_RBUTTONDOWN | WM_RBUTTONUP | WM_XBUTTONDOWN | WM_XBUTTONUP => { | WM_RBUTTONUP | WM_XBUTTONDOWN | WM_XBUTTONUP => {
let mut mouse_button_counter = (&*window_state_ptr).borrow().mouse_button_counter; let mut mouse_button_counter = (&*window_state_ptr).borrow().mouse_button_counter;
let button = match msg { let button = match msg {
@ -146,7 +137,8 @@ unsafe extern "system" fn wnd_proc(
(&*window_state_ptr).borrow_mut().mouse_button_counter = mouse_button_counter; (&*window_state_ptr).borrow_mut().mouse_button_counter = mouse_button_counter;
(&*window_state_ptr).borrow_mut() (&*window_state_ptr)
.borrow_mut()
.handler .handler
.on_event(&mut window, Event::Mouse(event)); .on_event(&mut window, Event::Mouse(event));
} }
@ -169,14 +161,16 @@ unsafe extern "system" fn wnd_proc(
// return 0; // return 0;
return DefWindowProcW(hwnd, msg, wparam, lparam); return DefWindowProcW(hwnd, msg, wparam, lparam);
} }
WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP | WM_SYSKEYUP
| WM_SYSKEYUP | WM_INPUTLANGCHANGE => { | WM_INPUTLANGCHANGE => {
let opt_event = (&*window_state_ptr).borrow_mut() let opt_event = (&*window_state_ptr)
.borrow_mut()
.keyboard_state .keyboard_state
.process_message(hwnd, msg, wparam, lparam); .process_message(hwnd, msg, wparam, lparam);
if let Some(event) = opt_event { if let Some(event) = opt_event {
(&*window_state_ptr).borrow_mut() (&*window_state_ptr)
.borrow_mut()
.handler .handler
.on_event(&mut window, Event::Keyboard(event)); .on_event(&mut window, Event::Keyboard(event));
} }
@ -198,10 +192,9 @@ unsafe extern "system" fn wnd_proc(
let window_info = window_state.window_info; let window_info = window_state.window_info;
window_state.handler.on_event( window_state
&mut window, .handler
Event::Window(WindowEvent::Resized(window_info)), .on_event(&mut window, Event::Window(WindowEvent::Resized(window_info)));
);
} }
WM_DPICHANGED => { WM_DPICHANGED => {
// To avoid weirdness with the realtime borrow checker. // To avoid weirdness with the realtime borrow checker.
@ -256,8 +249,6 @@ unsafe extern "system" fn wnd_proc(
} }
_ => {} _ => {}
} }
} }
return DefWindowProcW(hwnd, msg, wparam, lparam); return DefWindowProcW(hwnd, msg, wparam, lparam);
@ -266,9 +257,7 @@ unsafe extern "system" fn wnd_proc(
unsafe fn register_wnd_class() -> ATOM { unsafe fn register_wnd_class() -> ATOM {
// We generate a unique name for the new window class to prevent name collisions // We generate a unique name for the new window class to prevent name collisions
let class_name_str = format!("Baseview-{}", generate_guid()); let class_name_str = format!("Baseview-{}", generate_guid());
let mut class_name: Vec<u16> = OsStr::new(&class_name_str) let mut class_name: Vec<u16> = OsStr::new(&class_name_str).encode_wide().collect();
.encode_wide()
.collect();
class_name.push(0); class_name.push(0);
let wnd_class = WNDCLASSW { let wnd_class = WNDCLASSW {
@ -359,20 +348,14 @@ impl Window {
} }
} }
fn open<H, B>( fn open<H, B>(parented: bool, parent: HWND, options: WindowOpenOptions, build: B) -> HWND
parented: bool, where
parent: HWND, H: WindowHandler + 'static,
options: WindowOpenOptions,
build: B
) -> HWND
where H: WindowHandler + 'static,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
B: Send + 'static, B: Send + 'static,
{ {
unsafe { unsafe {
let mut title: Vec<u16> = OsStr::new(&options.title[..]) let mut title: Vec<u16> = OsStr::new(&options.title[..]).encode_wide().collect();
.encode_wide()
.collect();
title.push(0); title.push(0);
let window_class = register_wnd_class(); let window_class = register_wnd_class();
@ -380,7 +363,7 @@ impl Window {
let scaling = match options.scale { let scaling = match options.scale {
WindowScalePolicy::SystemScaleFactor => 1.0, WindowScalePolicy::SystemScaleFactor => 1.0,
WindowScalePolicy::ScaleFactor(scale) => scale WindowScalePolicy::ScaleFactor(scale) => scale,
}; };
let window_info = WindowInfo::from_logical_size(options.size, scaling); let window_info = WindowInfo::from_logical_size(options.size, scaling);

View file

@ -25,10 +25,7 @@ pub struct Window<'a> {
impl<'a> Window<'a> { impl<'a> Window<'a> {
pub(crate) fn new(window: &mut platform::Window) -> Window { pub(crate) fn new(window: &mut platform::Window) -> Window {
Window { Window { window, phantom: PhantomData }
window,
phantom: PhantomData,
}
} }
pub fn open_parented<P, H, B>(parent: &P, options: WindowOpenOptions, build: B) pub fn open_parented<P, H, B>(parent: &P, options: WindowOpenOptions, build: B)

View file

@ -16,12 +16,7 @@ impl WindowInfo {
height: (logical_size.height * scale).round() as u32, height: (logical_size.height * scale).round() as u32,
}; };
Self { Self { logical_size, physical_size, scale, scale_recip }
logical_size,
physical_size,
scale,
scale_recip,
}
} }
pub fn from_physical_size(physical_size: PhySize, scale: f64) -> Self { pub fn from_physical_size(physical_size: PhySize, scale: f64) -> Self {
@ -32,12 +27,7 @@ impl WindowInfo {
height: f64::from(physical_size.height) * scale_recip, height: f64::from(physical_size.height) * scale_recip,
}; };
Self { Self { logical_size, physical_size, scale, scale_recip }
logical_size,
physical_size,
scale,
scale_recip,
}
} }
/// The logical size of the window /// The logical size of the window
@ -65,7 +55,7 @@ impl WindowInfo {
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub struct Point { pub struct Point {
pub x: f64, pub x: f64,
pub y: f64 pub y: f64,
} }
impl Point { impl Point {
@ -88,7 +78,7 @@ impl Point {
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub struct PhyPoint { pub struct PhyPoint {
pub x: i32, pub x: i32,
pub y: i32 pub y: i32,
} }
impl PhyPoint { impl PhyPoint {

View file

@ -35,9 +35,8 @@ fn create_empty_cursor(display: *mut x11::xlib::Display) -> Option<u32> {
} }
fn load_cursor(display: *mut x11::xlib::Display, name: &[u8]) -> Option<u32> { fn load_cursor(display: *mut x11::xlib::Display, name: &[u8]) -> Option<u32> {
let xcursor = unsafe { let xcursor =
x11::xcursor::XcursorLibraryLoadCursor(display, name.as_ptr() as *const c_char) unsafe { x11::xcursor::XcursorLibraryLoadCursor(display, name.as_ptr() as *const c_char) };
};
if xcursor == 0 { if xcursor == 0 {
None None
@ -47,7 +46,8 @@ fn load_cursor(display: *mut x11::xlib::Display, name: &[u8]) -> Option<u32> {
} }
fn load_first_existing_cursor(display: *mut x11::xlib::Display, names: &[&[u8]]) -> Option<u32> { fn load_first_existing_cursor(display: *mut x11::xlib::Display, names: &[&[u8]]) -> Option<u32> {
names.iter() names
.iter()
.map(|name| load_cursor(display, name)) .map(|name| load_cursor(display, name))
.find(|xcursor| xcursor.is_some()) .find(|xcursor| xcursor.is_some())
.unwrap_or(None) .unwrap_or(None)
@ -101,7 +101,5 @@ pub(super) fn get_xcursor(display: *mut x11::xlib::Display, cursor: MouseCursor)
MouseCursor::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]), MouseCursor::RowResize => loadn(&[b"split_v\0", b"v_double_arrow\0"]),
}; };
cursor cursor.or(load(b"left_ptr\0")).unwrap_or(0)
.or(load(b"left_ptr\0"))
.unwrap_or(0)
} }

View file

@ -24,7 +24,6 @@ use keyboard_types::*;
use crate::keyboard::code_to_location; use crate::keyboard::code_to_location;
/// Convert a hardware scan code to a key. /// Convert a hardware scan code to a key.
/// ///
/// Note: this is a hardcoded layout. We need to detect the user's /// Note: this is a hardcoded layout. We need to detect the user's
@ -202,7 +201,6 @@ fn code_to_key(code: Code, m: Modifiers) -> Key {
} }
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
/// Map hardware keycode to code. /// Map hardware keycode to code.
/// ///
@ -385,10 +383,7 @@ fn key_mods(mods: u16) -> Modifiers {
ret ret
} }
pub(super) fn convert_key_press_event(key_press: &xcb::KeyPressEvent) -> KeyboardEvent {
pub(super) fn convert_key_press_event(
key_press: &xcb::KeyPressEvent,
) -> KeyboardEvent {
let hw_keycode = key_press.detail(); let hw_keycode = key_press.detail();
let code = hardware_keycode_to_code(hw_keycode.into()); let code = hardware_keycode_to_code(hw_keycode.into());
let modifiers = key_mods(key_press.state()); let modifiers = key_mods(key_press.state());
@ -396,21 +391,10 @@ pub(super) fn convert_key_press_event(
let location = code_to_location(code); let location = code_to_location(code);
let state = KeyState::Down; let state = KeyState::Down;
KeyboardEvent { KeyboardEvent { code, key, modifiers, location, state, repeat: false, is_composing: false }
code,
key,
modifiers,
location,
state,
repeat: false,
is_composing: false,
}
} }
pub(super) fn convert_key_release_event(key_release: &xcb::KeyReleaseEvent) -> KeyboardEvent {
pub(super) fn convert_key_release_event(
key_release: &xcb::KeyReleaseEvent
) -> KeyboardEvent {
let hw_keycode = key_release.detail(); let hw_keycode = key_release.detail();
let code = hardware_keycode_to_code(hw_keycode.into()); let code = hardware_keycode_to_code(hw_keycode.into());
let modifiers = key_mods(key_release.state()); let modifiers = key_mods(key_release.state());
@ -418,13 +402,5 @@ pub(super) fn convert_key_release_event(
let location = code_to_location(code); let location = code_to_location(code);
let state = KeyState::Up; let state = KeyState::Up;
KeyboardEvent { KeyboardEvent { code, key, modifiers, location, state, repeat: false, is_composing: false }
code,
key,
modifiers,
location,
state,
repeat: false,
is_composing: false,
}
} }

View file

@ -1,19 +1,14 @@
use std::os::raw::{c_ulong, c_void}; use std::os::raw::{c_ulong, c_void};
use std::sync::mpsc; use std::sync::mpsc;
use std::time::*;
use std::thread; use std::thread;
use std::time::*;
use raw_window_handle::{ use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
unix::XlibHandle,
HasRawWindowHandle,
RawWindowHandle
};
use super::XcbConnection; use super::XcbConnection;
use crate::{ use crate::{
Event, MouseButton, MouseCursor, MouseEvent, ScrollDelta, Event, MouseButton, MouseCursor, MouseEvent, PhyPoint, PhySize, ScrollDelta, WindowEvent,
WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions, WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy,
WindowScalePolicy, PhyPoint, PhySize,
}; };
use super::keyboard::{convert_key_press_event, convert_key_release_event}; use super::keyboard::{convert_key_press_event, convert_key_release_event};
@ -94,11 +89,10 @@ impl Window {
} }
fn window_thread<H, B>( fn window_thread<H, B>(
parent: Option<u32>, parent: Option<u32>, options: WindowOpenOptions, build: B,
options: WindowOpenOptions, build: B,
tx: mpsc::SyncSender<WindowOpenResult>, tx: mpsc::SyncSender<WindowOpenResult>,
) ) where
where H: WindowHandler + 'static, H: WindowHandler + 'static,
B: FnOnce(&mut crate::Window) -> H, B: FnOnce(&mut crate::Window) -> H,
B: Send + 'static, B: Send + 'static,
{ {
@ -108,10 +102,7 @@ impl Window {
// Get screen information (?) // Get screen information (?)
let setup = xcb_connection.conn.get_setup(); let setup = xcb_connection.conn.get_setup();
let screen = setup let screen = setup.roots().nth(xcb_connection.xlib_display as usize).unwrap();
.roots()
.nth(xcb_connection.xlib_display as usize)
.unwrap();
let foreground = xcb_connection.conn.generate_id(); let foreground = xcb_connection.conn.generate_id();
@ -121,15 +112,12 @@ impl Window {
&xcb_connection.conn, &xcb_connection.conn,
foreground, foreground,
parent_id, parent_id,
&[ &[(xcb::GC_FOREGROUND, screen.black_pixel()), (xcb::GC_GRAPHICS_EXPOSURES, 0)],
(xcb::GC_FOREGROUND, screen.black_pixel()),
(xcb::GC_GRAPHICS_EXPOSURES, 0),
],
); );
let scaling = match options.scale { let scaling = match options.scale {
WindowScalePolicy::SystemScaleFactor => xcb_connection.get_scaling().unwrap_or(1.0), WindowScalePolicy::SystemScaleFactor => xcb_connection.get_scaling().unwrap_or(1.0),
WindowScalePolicy::ScaleFactor(scale) => scale WindowScalePolicy::ScaleFactor(scale) => scale,
}; };
let window_info = WindowInfo::from_logical_size(options.size, scaling); let window_info = WindowInfo::from_logical_size(options.size, scaling);
@ -173,16 +161,16 @@ impl Window {
title.as_bytes(), title.as_bytes(),
); );
xcb_connection.atoms.wm_protocols xcb_connection.atoms.wm_protocols.zip(xcb_connection.atoms.wm_delete_window).map(
.zip(xcb_connection.atoms.wm_delete_window) |(wm_protocols, wm_delete_window)| {
.map(|(wm_protocols, wm_delete_window)| {
xcb_util::icccm::set_wm_protocols( xcb_util::icccm::set_wm_protocols(
&xcb_connection.conn, &xcb_connection.conn,
window_id, window_id,
wm_protocols, wm_protocols,
&[wm_delete_window], &[wm_delete_window],
); );
}); },
);
xcb_connection.conn.flush(); xcb_connection.conn.flush();
@ -204,7 +192,7 @@ impl Window {
// the correct dpi scaling. // the correct dpi scaling.
handler.on_event( handler.on_event(
&mut crate::Window::new(&mut window), &mut crate::Window::new(&mut window),
Event::Window(WindowEvent::Resized(window_info)) Event::Window(WindowEvent::Resized(window_info)),
); );
let _ = tx.send(Ok(SendableRwh(window.raw_window_handle()))); let _ = tx.send(Ok(SendableRwh(window.raw_window_handle())));
@ -218,7 +206,7 @@ impl Window {
pub fn set_mouse_cursor(&mut self, mouse_cursor: MouseCursor) { pub fn set_mouse_cursor(&mut self, mouse_cursor: MouseCursor) {
if self.mouse_cursor == mouse_cursor { if self.mouse_cursor == mouse_cursor {
return return;
} }
let xid = self.xcb_connection.get_cursor_xid(mouse_cursor); let xid = self.xcb_connection.get_cursor_xid(mouse_cursor);
@ -227,7 +215,7 @@ impl Window {
xcb::change_window_attributes( xcb::change_window_attributes(
&self.xcb_connection.conn, &self.xcb_connection.conn,
self.window_id, self.window_id,
&[(xcb::CW_CURSOR, xid)] &[(xcb::CW_CURSOR, xid)],
); );
self.xcb_connection.conn.flush(); self.xcb_connection.conn.flush();
@ -248,16 +236,13 @@ impl Window {
} }
if let Some(size) = self.new_physical_size.take() { if let Some(size) = self.new_physical_size.take() {
self.window_info = WindowInfo::from_physical_size( self.window_info = WindowInfo::from_physical_size(size, self.window_info.scale());
size,
self.window_info.scale()
);
let window_info = self.window_info; let window_info = self.window_info;
handler.on_event( handler.on_event(
&mut crate::Window::new(self), &mut crate::Window::new(self),
Event::Window(WindowEvent::Resized(window_info)) Event::Window(WindowEvent::Resized(window_info)),
); );
} }
} }
@ -343,13 +328,13 @@ impl Window {
let data = event.data().data; let data = event.data().data;
let (_, data32, _) = unsafe { data.align_to::<u32>() }; let (_, data32, _) = unsafe { data.align_to::<u32>() };
let wm_delete_window = self.xcb_connection.atoms.wm_delete_window let wm_delete_window =
.unwrap_or(xcb::NONE); self.xcb_connection.atoms.wm_delete_window.unwrap_or(xcb::NONE);
if wm_delete_window == data32[0] { if wm_delete_window == data32[0] {
handler.on_event( handler.on_event(
&mut crate::Window::new(self), &mut crate::Window::new(self),
Event::Window(WindowEvent::WillClose) Event::Window(WindowEvent::WillClose),
); );
// FIXME: handler should decide whether window stays open or not // FIXME: handler should decide whether window stays open or not
@ -362,7 +347,9 @@ impl Window {
let new_physical_size = PhySize::new(event.width() as u32, event.height() as u32); let new_physical_size = PhySize::new(event.width() as u32, event.height() as u32);
if self.new_physical_size.is_some() || new_physical_size != self.window_info.physical_size() { if self.new_physical_size.is_some()
|| new_physical_size != self.window_info.physical_size()
{
self.new_physical_size = Some(new_physical_size); self.new_physical_size = Some(new_physical_size);
} }
} }
@ -375,14 +362,13 @@ impl Window {
let detail = event.detail(); let detail = event.detail();
if detail != 4 && detail != 5 { if detail != 4 && detail != 5 {
let physical_pos = PhyPoint::new(event.event_x() as i32, event.event_y() as i32); let physical_pos =
PhyPoint::new(event.event_x() as i32, event.event_y() as i32);
let logical_pos = physical_pos.to_logical(&self.window_info); let logical_pos = physical_pos.to_logical(&self.window_info);
handler.on_event( handler.on_event(
&mut crate::Window::new(self), &mut crate::Window::new(self),
Event::Mouse(MouseEvent::CursorMoved { Event::Mouse(MouseEvent::CursorMoved { position: logical_pos }),
position: logical_pos,
}),
); );
} }
} }
@ -414,7 +400,7 @@ impl Window {
let button_id = mouse_id(detail); let button_id = mouse_id(detail);
handler.on_event( handler.on_event(
&mut crate::Window::new(self), &mut crate::Window::new(self),
Event::Mouse(MouseEvent::ButtonPressed(button_id)) Event::Mouse(MouseEvent::ButtonPressed(button_id)),
); );
} }
} }
@ -428,7 +414,7 @@ impl Window {
let button_id = mouse_id(detail); let button_id = mouse_id(detail);
handler.on_event( handler.on_event(
&mut crate::Window::new(self), &mut crate::Window::new(self),
Event::Mouse(MouseEvent::ButtonReleased(button_id)) Event::Mouse(MouseEvent::ButtonReleased(button_id)),
); );
} }
} }
@ -441,7 +427,7 @@ impl Window {
handler.on_event( handler.on_event(
&mut crate::Window::new(self), &mut crate::Window::new(self),
Event::Keyboard(convert_key_press_event(&event)) Event::Keyboard(convert_key_press_event(&event)),
); );
} }
@ -450,7 +436,7 @@ impl Window {
handler.on_event( handler.on_event(
&mut crate::Window::new(self), &mut crate::Window::new(self),
Event::Keyboard(convert_key_release_event(&event)) Event::Keyboard(convert_key_release_event(&event)),
); );
} }

View file

@ -1,15 +1,13 @@
use std::collections::HashMap;
/// A very light abstraction around the XCB connection. /// A very light abstraction around the XCB connection.
/// ///
/// Keeps track of the xcb connection itself and the xlib display ID that was used to connect. /// Keeps track of the xcb connection itself and the xlib display ID that was used to connect.
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::collections::HashMap;
use crate::MouseCursor; use crate::MouseCursor;
use super::cursor; use super::cursor;
pub(crate) struct Atoms { pub(crate) struct Atoms {
pub wm_protocols: Option<u32>, pub wm_protocols: Option<u32>,
pub wm_delete_window: Option<u32>, pub wm_delete_window: Option<u32>,
@ -48,19 +46,16 @@ impl XcbConnection {
conn.set_event_queue_owner(xcb::base::EventQueueOwner::Xcb); conn.set_event_queue_owner(xcb::base::EventQueueOwner::Xcb);
let (wm_protocols, wm_delete_window, wm_normal_hints) = intern_atoms!(&conn, WM_PROTOCOLS, WM_DELETE_WINDOW, WM_NORMAL_HINTS); let (wm_protocols, wm_delete_window, wm_normal_hints) =
intern_atoms!(&conn, WM_PROTOCOLS, WM_DELETE_WINDOW, WM_NORMAL_HINTS);
Ok(Self { Ok(Self {
conn, conn,
xlib_display, xlib_display,
atoms: Atoms { atoms: Atoms { wm_protocols, wm_delete_window, wm_normal_hints },
wm_protocols,
wm_delete_window,
wm_normal_hints,
},
cursor_cache: HashMap::new() cursor_cache: HashMap::new(),
}) })
} }
@ -79,10 +74,7 @@ impl XcbConnection {
if !rms.is_null() { if !rms.is_null() {
let db = XrmGetStringDatabase(rms); let db = XrmGetStringDatabase(rms);
if !db.is_null() { if !db.is_null() {
let mut value = XrmValue { let mut value = XrmValue { size: 0, addr: std::ptr::null_mut() };
size: 0,
addr: std::ptr::null_mut(),
};
let mut value_type: *mut std::os::raw::c_char = std::ptr::null_mut(); let mut value_type: *mut std::os::raw::c_char = std::ptr::null_mut();
let name_c_str = CString::new("Xft.dpi").unwrap(); let name_c_str = CString::new("Xft.dpi").unwrap();
@ -144,16 +136,13 @@ impl XcbConnection {
#[inline] #[inline]
pub fn get_scaling(&self) -> Option<f64> { pub fn get_scaling(&self) -> Option<f64> {
self.get_scaling_xft() self.get_scaling_xft().or(self.get_scaling_screen_dimensions())
.or(self.get_scaling_screen_dimensions())
} }
#[inline] #[inline]
pub fn get_cursor_xid(&mut self, cursor: MouseCursor) -> u32 { pub fn get_cursor_xid(&mut self, cursor: MouseCursor) -> u32 {
let dpy = self.conn.get_raw_dpy(); let dpy = self.conn.get_raw_dpy();
*self.cursor_cache *self.cursor_cache.entry(cursor).or_insert_with(|| cursor::get_xcursor(dpy, cursor))
.entry(cursor)
.or_insert_with(|| cursor::get_xcursor(dpy, cursor))
} }
} }