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:
parent
9fbfe18f9a
commit
2a894c6bc9
|
@ -1,2 +1,3 @@
|
|||
fn_args_layout = "Compressed"
|
||||
use_small_heuristics = "Max"
|
||||
use_field_init_shorthand = true
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use rtrb::{RingBuffer, Consumer};
|
||||
use rtrb::{Consumer, RingBuffer};
|
||||
|
||||
use baseview::{Event, EventStatus, Window, WindowHandler, WindowScalePolicy};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Message {
|
||||
Hello
|
||||
Hello,
|
||||
}
|
||||
|
||||
struct OpenWindowExample {
|
||||
|
@ -40,18 +40,13 @@ fn main() {
|
|||
|
||||
let (mut tx, rx) = RingBuffer::new(128).split();
|
||||
|
||||
::std::thread::spawn(move || {
|
||||
loop {
|
||||
::std::thread::spawn(move || loop {
|
||||
::std::thread::sleep(Duration::from_secs(5));
|
||||
|
||||
if let Err(_) = tx.push(Message::Hello) {
|
||||
println!("Failed sending message");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Window::open_blocking(
|
||||
window_open_options,
|
||||
|_| OpenWindowExample { rx }
|
||||
);
|
||||
Window::open_blocking(window_open_options, |_| OpenWindowExample { rx });
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use keyboard_types::KeyboardEvent;
|
||||
|
||||
use crate::{WindowInfo, Point};
|
||||
|
||||
use crate::{Point, WindowInfo};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum MouseButton {
|
||||
|
@ -83,7 +82,6 @@ pub enum Event {
|
|||
Window(WindowEvent),
|
||||
}
|
||||
|
||||
|
||||
/// Return value for [WindowHandler::on_event](`crate::WindowHandler::on_event()`),
|
||||
/// indicating whether the event was handled by your window or should be passed
|
||||
/// back to the platform.
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
use keyboard_types::{Code, Location};
|
||||
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
/// Map key code to location.
|
||||
///
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#[cfg(target_os = "macos")]
|
||||
mod macos;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod win;
|
||||
#[cfg(target_os = "linux")]
|
||||
mod x11;
|
||||
#[cfg(target_os = "macos")]
|
||||
mod macos;
|
||||
|
||||
mod event;
|
||||
mod keyboard;
|
||||
|
|
|
@ -19,14 +19,13 @@
|
|||
//! Conversion of platform keyboard event into cross-platform event.
|
||||
|
||||
use cocoa::appkit::{NSEvent, NSEventModifierFlags, NSEventType};
|
||||
use cocoa::foundation::NSString;
|
||||
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 crate::keyboard::code_to_location;
|
||||
|
||||
|
||||
pub(crate) fn from_nsstring(s: id) -> String {
|
||||
unsafe {
|
||||
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 {
|
||||
match s.chars().next() {
|
||||
None => false,
|
||||
|
@ -253,7 +251,6 @@ fn is_valid_key(s: &str) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn is_modifier_code(code: Code) -> bool {
|
||||
matches!(
|
||||
code,
|
||||
|
@ -270,7 +267,6 @@ fn is_modifier_code(code: Code) -> bool {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
impl KeyboardState {
|
||||
pub(crate) fn new() -> KeyboardState {
|
||||
let last_mods = NSEventModifierFlags::empty();
|
||||
|
@ -329,33 +325,21 @@ impl KeyboardState {
|
|||
}
|
||||
}
|
||||
};
|
||||
let event = KeyboardEvent {
|
||||
code,
|
||||
key,
|
||||
location,
|
||||
modifiers,
|
||||
state,
|
||||
is_composing,
|
||||
repeat,
|
||||
};
|
||||
let event =
|
||||
KeyboardEvent { code, key, location, modifiers, state, is_composing, repeat };
|
||||
Some(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const MODIFIER_MAP: &[(NSEventModifierFlags, Modifiers)] = &[
|
||||
(NSEventModifierFlags::NSShiftKeyMask, Modifiers::SHIFT),
|
||||
(NSEventModifierFlags::NSAlternateKeyMask, Modifiers::ALT),
|
||||
(NSEventModifierFlags::NSControlKeyMask, Modifiers::CONTROL),
|
||||
(NSEventModifierFlags::NSCommandKeyMask, Modifiers::META),
|
||||
(
|
||||
NSEventModifierFlags::NSAlphaShiftKeyMask,
|
||||
Modifiers::CAPS_LOCK,
|
||||
),
|
||||
(NSEventModifierFlags::NSAlphaShiftKeyMask, Modifiers::CAPS_LOCK),
|
||||
];
|
||||
|
||||
|
||||
pub(crate) fn make_modifiers(raw: NSEventModifierFlags) -> Modifiers {
|
||||
let mut modifiers = Modifiers::empty();
|
||||
for &(flags, mods) in MODIFIER_MAP {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
mod keyboard;
|
||||
mod window;
|
||||
mod view;
|
||||
mod window;
|
||||
|
||||
pub use window::*;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::ffi::c_void;
|
||||
|
||||
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 objc::{
|
||||
|
@ -13,16 +13,17 @@ use objc::{
|
|||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{Event, EventStatus, MouseButton, MouseEvent, Point, Size, WindowEvent, WindowInfo, WindowOpenOptions};
|
||||
use crate::MouseEvent::{ButtonPressed, ButtonReleased};
|
||||
use crate::{
|
||||
Event, EventStatus, MouseButton, MouseEvent, Point, Size, WindowEvent, WindowInfo,
|
||||
WindowOpenOptions,
|
||||
};
|
||||
|
||||
use super::window::WindowState;
|
||||
|
||||
|
||||
/// Name of the field used to store the `WindowState` pointer.
|
||||
pub(super) const BASEVIEW_STATE_IVAR: &str = "baseview_state";
|
||||
|
||||
|
||||
macro_rules! add_simple_mouse_class_method {
|
||||
($class:ident, $sel:ident, $event:expr) => {
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -41,7 +42,6 @@ macro_rules! add_simple_mouse_class_method {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
macro_rules! add_simple_keyboard_class_method {
|
||||
($class:ident, $sel:ident) => {
|
||||
#[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 view: id = msg_send![class, alloc];
|
||||
|
||||
let size = window_options.size;
|
||||
|
||||
view.initWithFrame_(NSRect::new(
|
||||
NSPoint::new(0., 0.),
|
||||
NSSize::new(size.width, size.height),
|
||||
));
|
||||
view.initWithFrame_(NSRect::new(NSPoint::new(0., 0.), NSSize::new(size.width, size.height)));
|
||||
|
||||
view
|
||||
}
|
||||
|
||||
|
||||
unsafe fn create_view_class() -> &'static Class {
|
||||
// Use unique class names so that there are no conflicts between different
|
||||
// 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(
|
||||
sel!(acceptsFirstResponder),
|
||||
property_yes as extern "C" fn(&Object, Sel) -> BOOL
|
||||
);
|
||||
class.add_method(
|
||||
sel!(isFlipped),
|
||||
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!(preservesContentInLiveResize),
|
||||
property_no as extern "C" fn(&Object, Sel) -> BOOL
|
||||
property_no as extern "C" fn(&Object, Sel) -> BOOL,
|
||||
);
|
||||
class.add_method(
|
||||
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(
|
||||
sel!(release),
|
||||
release as extern "C" fn(&mut Object, Sel)
|
||||
);
|
||||
class.add_method(
|
||||
sel!(dealloc),
|
||||
dealloc as extern "C" fn(&mut Object, Sel)
|
||||
);
|
||||
class.add_method(sel!(release), release as extern "C" fn(&mut Object, Sel));
|
||||
class.add_method(sel!(dealloc), dealloc as extern "C" fn(&mut Object, Sel));
|
||||
class.add_method(
|
||||
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(
|
||||
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(
|
||||
sel!(mouseMoved:),
|
||||
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(sel!(mouseMoved:), 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(
|
||||
sel!(viewDidChangeBackingProperties:),
|
||||
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!(
|
||||
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_mouse_class_method!(class, mouseDown, ButtonPressed(MouseButton::Left));
|
||||
add_simple_mouse_class_method!(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, keyUp);
|
||||
|
@ -206,32 +144,18 @@ unsafe fn create_view_class() -> &'static Class {
|
|||
class.register()
|
||||
}
|
||||
|
||||
|
||||
extern "C" fn property_yes(
|
||||
_this: &Object,
|
||||
_sel: Sel,
|
||||
) -> BOOL {
|
||||
extern "C" fn property_yes(_this: &Object, _sel: Sel) -> BOOL {
|
||||
YES
|
||||
}
|
||||
|
||||
|
||||
extern "C" fn property_no(
|
||||
_this: &Object,
|
||||
_sel: Sel,
|
||||
) -> BOOL {
|
||||
extern "C" fn property_no(_this: &Object, _sel: Sel) -> BOOL {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
extern "C" fn release(this: &mut Object, _sel: Sel) {
|
||||
// Hack for breaking circular references. We store the value of retainCount
|
||||
// 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);
|
||||
|
||||
if !state_ptr.is_null(){
|
||||
let retain_count_after_build = WindowState::from_field(this)
|
||||
.retain_count_after_build;
|
||||
if !state_ptr.is_null() {
|
||||
let retain_count_after_build = WindowState::from_field(this).retain_count_after_build;
|
||||
|
||||
if retain_count <= retain_count_after_build {
|
||||
WindowState::from_field(this).remove_timer();
|
||||
|
||||
this.set_ivar(
|
||||
BASEVIEW_STATE_IVAR,
|
||||
::std::ptr::null() as *const c_void
|
||||
);
|
||||
this.set_ivar(BASEVIEW_STATE_IVAR, ::std::ptr::null() as *const c_void);
|
||||
|
||||
// Drop WindowState
|
||||
Box::from_raw(state_ptr as *mut WindowState);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 {
|
||||
let ns_window: *mut Object = msg_send![this, window];
|
||||
|
||||
let scale_factor: f64 = if ns_window.is_null() {
|
||||
1.0
|
||||
} else {
|
||||
NSWindow::backingScaleFactor(ns_window) as f64
|
||||
};
|
||||
let scale_factor: f64 =
|
||||
if ns_window.is_null() { 1.0 } else { NSWindow::backingScaleFactor(ns_window) as f64 };
|
||||
|
||||
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(
|
||||
Size::new(bounds.size.width, bounds.size.height),
|
||||
scale_factor
|
||||
scale_factor,
|
||||
);
|
||||
|
||||
state.trigger_event(
|
||||
Event::Window(WindowEvent::Resized(window_info))
|
||||
);
|
||||
state.trigger_event(Event::Window(WindowEvent::Resized(window_info)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Init/reinit tracking area
|
||||
///
|
||||
/// Info:
|
||||
/// https://developer.apple.com/documentation/appkit/nstrackingarea
|
||||
/// https://developer.apple.com/documentation/appkit/nstrackingarea/options
|
||||
/// 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 mouse_entered_and_exited = 0x01;
|
||||
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_enabled_during_mouse_drag = 0x400;
|
||||
|
||||
mouse_entered_and_exited | tracking_mouse_moved |
|
||||
tracking_cursor_update | tracking_active_in_active_app |
|
||||
tracking_in_visible_rect | tracking_enabled_during_mouse_drag
|
||||
mouse_entered_and_exited
|
||||
| tracking_mouse_moved
|
||||
| tracking_cursor_update
|
||||
| tracking_active_in_active_app
|
||||
| tracking_in_visible_rect
|
||||
| tracking_enabled_during_mouse_drag
|
||||
};
|
||||
|
||||
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 {
|
||||
let tracking_areas: *mut Object = msg_send![this, trackingAreas];
|
||||
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 tracking_area_count != 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];
|
||||
}
|
||||
|
||||
} else {
|
||||
if tracking_area_count == 0 {
|
||||
let class = Class::get("NSTrackingArea").unwrap();
|
||||
|
@ -372,27 +281,22 @@ extern "C" fn view_will_move_to_window(
|
|||
|
||||
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, makeFirstResponder:this];
|
||||
let _: () = msg_send![new_window, setAcceptsMouseMovedEvents: YES];
|
||||
let _: () = msg_send![new_window, makeFirstResponder: this];
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
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 {
|
||||
let tracking_areas: *mut Object = msg_send![this, trackingAreas];
|
||||
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
|
||||
){
|
||||
let state: &mut WindowState = unsafe {
|
||||
WindowState::from_field(this)
|
||||
};
|
||||
extern "C" fn mouse_moved(this: &Object, _sel: Sel, event: id) {
|
||||
let state: &mut WindowState = unsafe { WindowState::from_field(this) };
|
||||
|
||||
let point: NSPoint = unsafe {
|
||||
let point = NSEvent::locationInWindow(event);
|
||||
|
@ -417,12 +314,7 @@ extern "C" fn mouse_moved(
|
|||
msg_send![this, convertPoint:point fromView:nil]
|
||||
};
|
||||
|
||||
let position = Point {
|
||||
x: point.x,
|
||||
y: point.y
|
||||
};
|
||||
let position = Point { x: point.x, y: point.y };
|
||||
|
||||
state.trigger_event(
|
||||
Event::Mouse(MouseEvent::CursorMoved { position })
|
||||
);
|
||||
state.trigger_event(Event::Mouse(MouseEvent::CursorMoved { position }));
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use std::ffi::c_void;
|
||||
|
||||
use cocoa::appkit::{
|
||||
NSApp, NSApplication, NSApplicationActivationPolicyRegular,
|
||||
NSBackingStoreBuffered, NSWindow, NSWindowStyleMask,
|
||||
NSApp, NSApplication, NSApplicationActivationPolicyRegular, NSBackingStoreBuffered, NSWindow,
|
||||
NSWindowStyleMask,
|
||||
};
|
||||
use cocoa::base::{id, nil, NO};
|
||||
use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString};
|
||||
use core_foundation::runloop::{
|
||||
CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer,
|
||||
kCFRunLoopDefaultMode,
|
||||
CFRunLoop, CFRunLoopTimer, CFRunLoopTimerContext, __CFRunLoopTimer, kCFRunLoopDefaultMode,
|
||||
};
|
||||
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 crate::{
|
||||
Event, EventStatus, WindowHandler, WindowOpenOptions, WindowScalePolicy,
|
||||
WindowInfo,
|
||||
};
|
||||
use crate::{Event, EventStatus, WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy};
|
||||
|
||||
use super::view::{create_view, BASEVIEW_STATE_IVAR};
|
||||
use super::keyboard::KeyboardState;
|
||||
|
||||
use super::view::{create_view, BASEVIEW_STATE_IVAR};
|
||||
|
||||
pub struct Window {
|
||||
/// 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 window = Window {
|
||||
ns_window: None,
|
||||
ns_view,
|
||||
};
|
||||
let window = Window { ns_window: None, ns_view };
|
||||
|
||||
Self::init(window, build);
|
||||
|
||||
|
@ -76,10 +68,7 @@ impl Window {
|
|||
|
||||
let ns_view = unsafe { create_view(&options) };
|
||||
|
||||
let window = Window {
|
||||
ns_window: None,
|
||||
ns_view,
|
||||
};
|
||||
let window = Window { ns_window: None, ns_view };
|
||||
|
||||
let raw_window_handle = window.raw_window_handle();
|
||||
|
||||
|
@ -108,9 +97,7 @@ impl Window {
|
|||
let app = unsafe { NSApp() };
|
||||
|
||||
unsafe {
|
||||
app.setActivationPolicy_(
|
||||
NSApplicationActivationPolicyRegular
|
||||
);
|
||||
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
|
||||
}
|
||||
|
||||
let scaling = match options.scale {
|
||||
|
@ -118,22 +105,18 @@ impl Window {
|
|||
WindowScalePolicy::SystemScaleFactor => 1.0,
|
||||
};
|
||||
|
||||
let window_info = WindowInfo::from_logical_size(
|
||||
options.size,
|
||||
scaling
|
||||
);
|
||||
let window_info = WindowInfo::from_logical_size(options.size, scaling);
|
||||
|
||||
let rect = NSRect::new(
|
||||
NSPoint::new(0.0, 0.0),
|
||||
NSSize::new(
|
||||
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 = NSWindow::alloc(nil)
|
||||
.initWithContentRect_styleMask_backing_defer_(
|
||||
let ns_window = NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_(
|
||||
rect,
|
||||
NSWindowStyleMask::NSTitledWindowMask,
|
||||
NSBackingStoreBuffered,
|
||||
|
@ -141,9 +124,7 @@ impl Window {
|
|||
);
|
||||
ns_window.center();
|
||||
|
||||
let title = NSString::alloc(nil)
|
||||
.init_str(&options.title)
|
||||
.autorelease();
|
||||
let title = NSString::alloc(nil).init_str(&options.title).autorelease();
|
||||
ns_window.setTitle_(title);
|
||||
|
||||
ns_window.makeKeyAndOrderFront_(nil);
|
||||
|
@ -153,10 +134,7 @@ impl Window {
|
|||
|
||||
let ns_view = unsafe { create_view(&options) };
|
||||
|
||||
let window = Window {
|
||||
ns_window: Some(ns_window),
|
||||
ns_view,
|
||||
};
|
||||
let window = Window { ns_window: Some(ns_window), ns_view };
|
||||
|
||||
Self::init(window, build);
|
||||
|
||||
|
@ -170,19 +148,15 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn init<H, B>(
|
||||
mut window: Window,
|
||||
build: B
|
||||
)
|
||||
where H: WindowHandler + 'static,
|
||||
fn init<H, B>(mut window: Window, build: B)
|
||||
where
|
||||
H: WindowHandler + 'static,
|
||||
B: FnOnce(&mut crate::Window) -> H,
|
||||
B: Send + 'static,
|
||||
{
|
||||
let window_handler = Box::new(build(&mut crate::Window::new(&mut window)));
|
||||
|
||||
let retain_count_after_build: usize = unsafe {
|
||||
msg_send![window.ns_view, retainCount]
|
||||
};
|
||||
let retain_count_after_build: usize = unsafe { msg_send![window.ns_view, retainCount] };
|
||||
|
||||
let window_state_ptr = Box::into_raw(Box::new(WindowState {
|
||||
window,
|
||||
|
@ -193,17 +167,14 @@ impl Window {
|
|||
}));
|
||||
|
||||
unsafe {
|
||||
(*(*window_state_ptr).window.ns_view).set_ivar(
|
||||
BASEVIEW_STATE_IVAR,
|
||||
window_state_ptr as *mut c_void
|
||||
);
|
||||
(*(*window_state_ptr).window.ns_view)
|
||||
.set_ivar(BASEVIEW_STATE_IVAR, window_state_ptr as *mut c_void);
|
||||
|
||||
WindowState::setup_timer(window_state_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub(super) struct WindowState {
|
||||
window: Window,
|
||||
window_handler: Box<dyn WindowHandler>,
|
||||
|
@ -212,7 +183,6 @@ pub(super) struct WindowState {
|
|||
pub retain_count_after_build: usize,
|
||||
}
|
||||
|
||||
|
||||
impl WindowState {
|
||||
/// 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 {
|
||||
self.window_handler
|
||||
.on_event(&mut crate::Window::new(&mut self.window), event)
|
||||
self.window_handler.on_event(&mut crate::Window::new(&mut self.window), event)
|
||||
}
|
||||
|
||||
pub(super) fn trigger_frame(&mut self) {
|
||||
self.window_handler
|
||||
.on_frame(&mut crate::Window::new(&mut self.window));
|
||||
self.window_handler.on_frame(&mut crate::Window::new(&mut self.window));
|
||||
}
|
||||
|
||||
pub(super) fn process_native_key_event(
|
||||
&mut self,
|
||||
event: *mut Object
|
||||
) -> Option<KeyboardEvent> {
|
||||
pub(super) fn process_native_key_event(&mut self, event: *mut Object) -> Option<KeyboardEvent> {
|
||||
self.keyboard_state.process_native_event(event)
|
||||
}
|
||||
|
||||
/// Don't call until WindowState pointer is stored in view
|
||||
unsafe fn setup_timer(window_state_ptr: *mut WindowState) {
|
||||
extern "C" fn timer_callback(
|
||||
_: *mut __CFRunLoopTimer,
|
||||
window_state_ptr: *mut c_void,
|
||||
) {
|
||||
extern "C" fn timer_callback(_: *mut __CFRunLoopTimer, window_state_ptr: *mut c_void) {
|
||||
unsafe {
|
||||
let window_state = &mut *(
|
||||
window_state_ptr as *mut WindowState
|
||||
);
|
||||
let window_state = &mut *(window_state_ptr as *mut WindowState);
|
||||
|
||||
window_state.trigger_frame();
|
||||
}
|
||||
|
@ -265,17 +225,9 @@ impl WindowState {
|
|||
copyDescription: None,
|
||||
};
|
||||
|
||||
let timer = CFRunLoopTimer::new(
|
||||
0.0,
|
||||
0.015,
|
||||
0,
|
||||
0,
|
||||
timer_callback,
|
||||
&mut timer_context,
|
||||
);
|
||||
let timer = CFRunLoopTimer::new(0.0, 0.015, 0, 0, timer_callback, &mut timer_context);
|
||||
|
||||
CFRunLoop::get_current()
|
||||
.add_timer(&timer, kCFRunLoopDefaultMode);
|
||||
CFRunLoop::get_current().add_timer(&timer, kCFRunLoopDefaultMode);
|
||||
|
||||
let window_state = &mut *(window_state_ptr);
|
||||
|
||||
|
@ -285,18 +237,14 @@ impl WindowState {
|
|||
/// Call when freeing view
|
||||
pub(super) unsafe fn remove_timer(&mut self) {
|
||||
if let Some(frame_timer) = self.frame_timer.take() {
|
||||
CFRunLoop::get_current()
|
||||
.remove_timer(&frame_timer, kCFRunLoopDefaultMode);
|
||||
CFRunLoop::get_current().remove_timer(&frame_timer, kCFRunLoopDefaultMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsafe impl HasRawWindowHandle for Window {
|
||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
let ns_window = self.ns_window.unwrap_or(
|
||||
::std::ptr::null_mut()
|
||||
) as *mut c_void;
|
||||
let ns_window = self.ns_window.unwrap_or(::std::ptr::null_mut()) as *mut c_void;
|
||||
|
||||
RawWindowHandle::MacOS(MacOSHandle {
|
||||
ns_window,
|
||||
|
|
|
@ -23,7 +23,7 @@ use std::convert::TryInto;
|
|||
use std::mem;
|
||||
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::ntdef::SHORT;
|
||||
|
@ -502,14 +502,8 @@ impl KeyboardState {
|
|||
let stash_vk = None;
|
||||
let stash_utf16 = Vec::new();
|
||||
let has_altgr = false;
|
||||
let mut result = KeyboardState {
|
||||
hkl,
|
||||
key_vals,
|
||||
dead_keys,
|
||||
has_altgr,
|
||||
stash_vk,
|
||||
stash_utf16,
|
||||
};
|
||||
let mut result =
|
||||
KeyboardState { hkl, key_vals, dead_keys, has_altgr, stash_vk, stash_utf16 };
|
||||
result.load_keyboard_layout();
|
||||
result
|
||||
}
|
||||
|
@ -548,11 +542,7 @@ impl KeyboardState {
|
|||
/// a valid `HKL` reference in the `WM_INPUTLANGCHANGE` message. Actual danger
|
||||
/// is likely low, though.
|
||||
pub(crate) unsafe fn process_message(
|
||||
&mut self,
|
||||
hwnd: HWND,
|
||||
msg: UINT,
|
||||
wparam: WPARAM,
|
||||
lparam: LPARAM,
|
||||
&mut self, hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM,
|
||||
) -> Option<KeyboardEvent> {
|
||||
match msg {
|
||||
WM_KEYDOWN | WM_SYSKEYDOWN => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
mod window;
|
||||
mod keyboard;
|
||||
mod window;
|
||||
|
||||
pub use window::*;
|
||||
|
|
|
@ -3,35 +3,29 @@ use winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM};
|
|||
use winapi::shared::windef::{HWND, RECT};
|
||||
use winapi::um::combaseapi::CoCreateGuid;
|
||||
use winapi::um::winuser::{
|
||||
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DispatchMessageW,
|
||||
GetMessageW, GetWindowLongPtrW, PostMessageW, RegisterClassW, SetTimer,
|
||||
SetWindowLongPtrW, TranslateMessage, UnregisterClassW, LoadCursorW,
|
||||
DestroyWindow, SetProcessDpiAwarenessContext, SetWindowPos,
|
||||
GetDpiForWindow,
|
||||
CS_OWNDC, GWLP_USERDATA, IDC_ARROW,
|
||||
MSG, WM_CLOSE, WM_CREATE, WM_MOUSEMOVE, WM_MOUSEWHEEL, WHEEL_DELTA, WM_SHOWWINDOW, WM_TIMER,
|
||||
WM_NCDESTROY, WNDCLASSW, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
|
||||
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE, WM_DPICHANGED, WM_CHAR, WM_SYSCHAR, WM_KEYDOWN,
|
||||
WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP, WM_INPUTLANGCHANGE, WM_SIZE,
|
||||
GET_XBUTTON_WPARAM, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP,
|
||||
WM_RBUTTONDOWN, WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2,
|
||||
SetCapture, GetCapture, ReleaseCapture, IsWindow, SWP_NOZORDER, SWP_NOMOVE
|
||||
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW,
|
||||
GetCapture, GetDpiForWindow, GetMessageW, GetWindowLongPtrW, IsWindow, LoadCursorW,
|
||||
PostMessageW, RegisterClassW, ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext,
|
||||
SetTimer, SetWindowLongPtrW, SetWindowPos, TranslateMessage, UnregisterClassW, CS_OWNDC,
|
||||
GET_XBUTTON_WPARAM, GWLP_USERDATA, IDC_ARROW, MSG, SWP_NOMOVE, SWP_NOZORDER, WHEEL_DELTA,
|
||||
WM_CHAR, WM_CLOSE, WM_CREATE, WM_DPICHANGED, WM_INPUTLANGCHANGE, WM_KEYDOWN, WM_KEYUP,
|
||||
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL,
|
||||
WM_NCDESTROY, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SHOWWINDOW, WM_SIZE, WM_SYSCHAR, WM_SYSKEYDOWN,
|
||||
WM_SYSKEYUP, WM_TIMER, WM_XBUTTONDOWN, WM_XBUTTONUP, WNDCLASSW, WS_CAPTION, WS_CHILD,
|
||||
WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
|
||||
XBUTTON1, XBUTTON2,
|
||||
};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::{OsStr, c_void};
|
||||
use std::ffi::{c_void, OsStr};
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::ptr::null_mut;
|
||||
|
||||
use raw_window_handle::{
|
||||
windows::WindowsHandle,
|
||||
HasRawWindowHandle,
|
||||
RawWindowHandle
|
||||
};
|
||||
use raw_window_handle::{windows::WindowsHandle, HasRawWindowHandle, RawWindowHandle};
|
||||
|
||||
use crate::{
|
||||
Event, MouseButton, MouseEvent, ScrollDelta, WindowEvent,
|
||||
WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy, PhyPoint, PhySize
|
||||
Event, MouseButton, MouseEvent, PhyPoint, PhySize, ScrollDelta, WindowEvent, WindowHandler,
|
||||
WindowInfo, WindowOpenOptions, WindowScalePolicy,
|
||||
};
|
||||
|
||||
use super::keyboard::KeyboardState;
|
||||
|
@ -83,9 +77,7 @@ unsafe extern "system" fn wnd_proc(
|
|||
|
||||
window_state.handler.on_event(
|
||||
&mut window,
|
||||
Event::Mouse(MouseEvent::CursorMoved {
|
||||
position: logical_pos,
|
||||
}),
|
||||
Event::Mouse(MouseEvent::CursorMoved { position: logical_pos }),
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,9 +97,8 @@ unsafe extern "system" fn wnd_proc(
|
|||
);
|
||||
return 0;
|
||||
}
|
||||
WM_LBUTTONDOWN | WM_LBUTTONUP | WM_MBUTTONDOWN | WM_MBUTTONUP |
|
||||
WM_RBUTTONDOWN | WM_RBUTTONUP | WM_XBUTTONDOWN | WM_XBUTTONUP => {
|
||||
|
||||
WM_LBUTTONDOWN | WM_LBUTTONUP | WM_MBUTTONDOWN | WM_MBUTTONUP | WM_RBUTTONDOWN
|
||||
| WM_RBUTTONUP | WM_XBUTTONDOWN | WM_XBUTTONUP => {
|
||||
let mut mouse_button_counter = (&*window_state_ptr).borrow().mouse_button_counter;
|
||||
|
||||
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()
|
||||
(&*window_state_ptr)
|
||||
.borrow_mut()
|
||||
.handler
|
||||
.on_event(&mut window, Event::Mouse(event));
|
||||
}
|
||||
|
@ -169,14 +161,16 @@ unsafe extern "system" fn wnd_proc(
|
|||
// return 0;
|
||||
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP
|
||||
| WM_SYSKEYUP | WM_INPUTLANGCHANGE => {
|
||||
let opt_event = (&*window_state_ptr).borrow_mut()
|
||||
WM_CHAR | WM_SYSCHAR | WM_KEYDOWN | WM_SYSKEYDOWN | WM_KEYUP | WM_SYSKEYUP
|
||||
| WM_INPUTLANGCHANGE => {
|
||||
let opt_event = (&*window_state_ptr)
|
||||
.borrow_mut()
|
||||
.keyboard_state
|
||||
.process_message(hwnd, msg, wparam, lparam);
|
||||
|
||||
if let Some(event) = opt_event {
|
||||
(&*window_state_ptr).borrow_mut()
|
||||
(&*window_state_ptr)
|
||||
.borrow_mut()
|
||||
.handler
|
||||
.on_event(&mut window, Event::Keyboard(event));
|
||||
}
|
||||
|
@ -198,10 +192,9 @@ unsafe extern "system" fn wnd_proc(
|
|||
|
||||
let window_info = window_state.window_info;
|
||||
|
||||
window_state.handler.on_event(
|
||||
&mut window,
|
||||
Event::Window(WindowEvent::Resized(window_info)),
|
||||
);
|
||||
window_state
|
||||
.handler
|
||||
.on_event(&mut window, Event::Window(WindowEvent::Resized(window_info)));
|
||||
}
|
||||
WM_DPICHANGED => {
|
||||
// To avoid weirdness with the realtime borrow checker.
|
||||
|
@ -256,8 +249,6 @@ unsafe extern "system" fn wnd_proc(
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
|
@ -266,9 +257,7 @@ unsafe extern "system" fn wnd_proc(
|
|||
unsafe fn register_wnd_class() -> ATOM {
|
||||
// We generate a unique name for the new window class to prevent name collisions
|
||||
let class_name_str = format!("Baseview-{}", generate_guid());
|
||||
let mut class_name: Vec<u16> = OsStr::new(&class_name_str)
|
||||
.encode_wide()
|
||||
.collect();
|
||||
let mut class_name: Vec<u16> = OsStr::new(&class_name_str).encode_wide().collect();
|
||||
class_name.push(0);
|
||||
|
||||
let wnd_class = WNDCLASSW {
|
||||
|
@ -359,20 +348,14 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn open<H, B>(
|
||||
parented: bool,
|
||||
parent: HWND,
|
||||
options: WindowOpenOptions,
|
||||
build: B
|
||||
) -> HWND
|
||||
where H: WindowHandler + 'static,
|
||||
fn open<H, B>(parented: bool, parent: HWND, options: WindowOpenOptions, build: B) -> HWND
|
||||
where
|
||||
H: WindowHandler + 'static,
|
||||
B: FnOnce(&mut crate::Window) -> H,
|
||||
B: Send + 'static,
|
||||
{
|
||||
unsafe {
|
||||
let mut title: Vec<u16> = OsStr::new(&options.title[..])
|
||||
.encode_wide()
|
||||
.collect();
|
||||
let mut title: Vec<u16> = OsStr::new(&options.title[..]).encode_wide().collect();
|
||||
title.push(0);
|
||||
|
||||
let window_class = register_wnd_class();
|
||||
|
@ -380,7 +363,7 @@ impl Window {
|
|||
|
||||
let scaling = match options.scale {
|
||||
WindowScalePolicy::SystemScaleFactor => 1.0,
|
||||
WindowScalePolicy::ScaleFactor(scale) => scale
|
||||
WindowScalePolicy::ScaleFactor(scale) => scale,
|
||||
};
|
||||
|
||||
let window_info = WindowInfo::from_logical_size(options.size, scaling);
|
||||
|
|
|
@ -25,10 +25,7 @@ pub struct Window<'a> {
|
|||
|
||||
impl<'a> Window<'a> {
|
||||
pub(crate) fn new(window: &mut platform::Window) -> Window {
|
||||
Window {
|
||||
window,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
Window { window, phantom: PhantomData }
|
||||
}
|
||||
|
||||
pub fn open_parented<P, H, B>(parent: &P, options: WindowOpenOptions, build: B)
|
||||
|
|
|
@ -16,12 +16,7 @@ impl WindowInfo {
|
|||
height: (logical_size.height * scale).round() as u32,
|
||||
};
|
||||
|
||||
Self {
|
||||
logical_size,
|
||||
physical_size,
|
||||
scale,
|
||||
scale_recip,
|
||||
}
|
||||
Self { logical_size, physical_size, scale, scale_recip }
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
Self {
|
||||
logical_size,
|
||||
physical_size,
|
||||
scale,
|
||||
scale_recip,
|
||||
}
|
||||
Self { logical_size, physical_size, scale, scale_recip }
|
||||
}
|
||||
|
||||
/// The logical size of the window
|
||||
|
@ -65,7 +55,7 @@ impl WindowInfo {
|
|||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Point {
|
||||
pub x: f64,
|
||||
pub y: f64
|
||||
pub y: f64,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
|
@ -88,7 +78,7 @@ impl Point {
|
|||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct PhyPoint {
|
||||
pub x: i32,
|
||||
pub y: i32
|
||||
pub y: i32,
|
||||
}
|
||||
|
||||
impl PhyPoint {
|
||||
|
|
|
@ -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> {
|
||||
let xcursor = unsafe {
|
||||
x11::xcursor::XcursorLibraryLoadCursor(display, name.as_ptr() as *const c_char)
|
||||
};
|
||||
let xcursor =
|
||||
unsafe { x11::xcursor::XcursorLibraryLoadCursor(display, name.as_ptr() as *const c_char) };
|
||||
|
||||
if xcursor == 0 {
|
||||
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> {
|
||||
names.iter()
|
||||
names
|
||||
.iter()
|
||||
.map(|name| load_cursor(display, name))
|
||||
.find(|xcursor| xcursor.is_some())
|
||||
.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"]),
|
||||
};
|
||||
|
||||
cursor
|
||||
.or(load(b"left_ptr\0"))
|
||||
.unwrap_or(0)
|
||||
cursor.or(load(b"left_ptr\0")).unwrap_or(0)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ use keyboard_types::*;
|
|||
|
||||
use crate::keyboard::code_to_location;
|
||||
|
||||
|
||||
/// Convert a hardware scan code to a key.
|
||||
///
|
||||
/// 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")]
|
||||
/// Map hardware keycode to code.
|
||||
///
|
||||
|
@ -385,10 +383,7 @@ fn key_mods(mods: u16) -> Modifiers {
|
|||
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 code = hardware_keycode_to_code(hw_keycode.into());
|
||||
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 state = KeyState::Down;
|
||||
|
||||
KeyboardEvent {
|
||||
code,
|
||||
key,
|
||||
modifiers,
|
||||
location,
|
||||
state,
|
||||
repeat: false,
|
||||
is_composing: false,
|
||||
}
|
||||
KeyboardEvent { 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 code = hardware_keycode_to_code(hw_keycode.into());
|
||||
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 state = KeyState::Up;
|
||||
|
||||
KeyboardEvent {
|
||||
code,
|
||||
key,
|
||||
modifiers,
|
||||
location,
|
||||
state,
|
||||
repeat: false,
|
||||
is_composing: false,
|
||||
}
|
||||
KeyboardEvent { code, key, modifiers, location, state, repeat: false, is_composing: false }
|
||||
}
|
|
@ -1,19 +1,14 @@
|
|||
use std::os::raw::{c_ulong, c_void};
|
||||
use std::sync::mpsc;
|
||||
use std::time::*;
|
||||
use std::thread;
|
||||
use std::time::*;
|
||||
|
||||
use raw_window_handle::{
|
||||
unix::XlibHandle,
|
||||
HasRawWindowHandle,
|
||||
RawWindowHandle
|
||||
};
|
||||
use raw_window_handle::{unix::XlibHandle, HasRawWindowHandle, RawWindowHandle};
|
||||
|
||||
use super::XcbConnection;
|
||||
use crate::{
|
||||
Event, MouseButton, MouseCursor, MouseEvent, ScrollDelta,
|
||||
WindowEvent, WindowHandler, WindowInfo, WindowOpenOptions,
|
||||
WindowScalePolicy, PhyPoint, PhySize,
|
||||
Event, MouseButton, MouseCursor, MouseEvent, PhyPoint, PhySize, ScrollDelta, WindowEvent,
|
||||
WindowHandler, WindowInfo, WindowOpenOptions, WindowScalePolicy,
|
||||
};
|
||||
|
||||
use super::keyboard::{convert_key_press_event, convert_key_release_event};
|
||||
|
@ -94,11 +89,10 @@ impl Window {
|
|||
}
|
||||
|
||||
fn window_thread<H, B>(
|
||||
parent: Option<u32>,
|
||||
options: WindowOpenOptions, build: B,
|
||||
parent: Option<u32>, options: WindowOpenOptions, build: B,
|
||||
tx: mpsc::SyncSender<WindowOpenResult>,
|
||||
)
|
||||
where H: WindowHandler + 'static,
|
||||
) where
|
||||
H: WindowHandler + 'static,
|
||||
B: FnOnce(&mut crate::Window) -> H,
|
||||
B: Send + 'static,
|
||||
{
|
||||
|
@ -108,10 +102,7 @@ impl Window {
|
|||
|
||||
// Get screen information (?)
|
||||
let setup = xcb_connection.conn.get_setup();
|
||||
let screen = setup
|
||||
.roots()
|
||||
.nth(xcb_connection.xlib_display as usize)
|
||||
.unwrap();
|
||||
let screen = setup.roots().nth(xcb_connection.xlib_display as usize).unwrap();
|
||||
|
||||
let foreground = xcb_connection.conn.generate_id();
|
||||
|
||||
|
@ -121,15 +112,12 @@ impl Window {
|
|||
&xcb_connection.conn,
|
||||
foreground,
|
||||
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 {
|
||||
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);
|
||||
|
@ -173,16 +161,16 @@ impl Window {
|
|||
title.as_bytes(),
|
||||
);
|
||||
|
||||
xcb_connection.atoms.wm_protocols
|
||||
.zip(xcb_connection.atoms.wm_delete_window)
|
||||
.map(|(wm_protocols, wm_delete_window)| {
|
||||
xcb_connection.atoms.wm_protocols.zip(xcb_connection.atoms.wm_delete_window).map(
|
||||
|(wm_protocols, wm_delete_window)| {
|
||||
xcb_util::icccm::set_wm_protocols(
|
||||
&xcb_connection.conn,
|
||||
window_id,
|
||||
wm_protocols,
|
||||
&[wm_delete_window],
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
xcb_connection.conn.flush();
|
||||
|
||||
|
@ -204,7 +192,7 @@ impl Window {
|
|||
// the correct dpi scaling.
|
||||
handler.on_event(
|
||||
&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())));
|
||||
|
@ -218,7 +206,7 @@ impl Window {
|
|||
|
||||
pub fn set_mouse_cursor(&mut self, mouse_cursor: MouseCursor) {
|
||||
if self.mouse_cursor == mouse_cursor {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
let xid = self.xcb_connection.get_cursor_xid(mouse_cursor);
|
||||
|
@ -227,7 +215,7 @@ impl Window {
|
|||
xcb::change_window_attributes(
|
||||
&self.xcb_connection.conn,
|
||||
self.window_id,
|
||||
&[(xcb::CW_CURSOR, xid)]
|
||||
&[(xcb::CW_CURSOR, xid)],
|
||||
);
|
||||
|
||||
self.xcb_connection.conn.flush();
|
||||
|
@ -248,16 +236,13 @@ impl Window {
|
|||
}
|
||||
|
||||
if let Some(size) = self.new_physical_size.take() {
|
||||
self.window_info = WindowInfo::from_physical_size(
|
||||
size,
|
||||
self.window_info.scale()
|
||||
);
|
||||
self.window_info = WindowInfo::from_physical_size(size, self.window_info.scale());
|
||||
|
||||
let window_info = self.window_info;
|
||||
|
||||
handler.on_event(
|
||||
&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 (_, data32, _) = unsafe { data.align_to::<u32>() };
|
||||
|
||||
let wm_delete_window = self.xcb_connection.atoms.wm_delete_window
|
||||
.unwrap_or(xcb::NONE);
|
||||
let wm_delete_window =
|
||||
self.xcb_connection.atoms.wm_delete_window.unwrap_or(xcb::NONE);
|
||||
|
||||
if wm_delete_window == data32[0] {
|
||||
handler.on_event(
|
||||
&mut crate::Window::new(self),
|
||||
Event::Window(WindowEvent::WillClose)
|
||||
Event::Window(WindowEvent::WillClose),
|
||||
);
|
||||
|
||||
// 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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -375,14 +362,13 @@ impl Window {
|
|||
let detail = event.detail();
|
||||
|
||||
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);
|
||||
|
||||
handler.on_event(
|
||||
&mut crate::Window::new(self),
|
||||
Event::Mouse(MouseEvent::CursorMoved {
|
||||
position: logical_pos,
|
||||
}),
|
||||
Event::Mouse(MouseEvent::CursorMoved { position: logical_pos }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -414,7 +400,7 @@ impl Window {
|
|||
let button_id = mouse_id(detail);
|
||||
handler.on_event(
|
||||
&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);
|
||||
handler.on_event(
|
||||
&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(
|
||||
&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(
|
||||
&mut crate::Window::new(self),
|
||||
Event::Keyboard(convert_key_release_event(&event))
|
||||
Event::Keyboard(convert_key_release_event(&event)),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
use std::collections::HashMap;
|
||||
/// 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.
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::MouseCursor;
|
||||
|
||||
use super::cursor;
|
||||
|
||||
|
||||
pub(crate) struct Atoms {
|
||||
pub wm_protocols: Option<u32>,
|
||||
pub wm_delete_window: Option<u32>,
|
||||
|
@ -48,19 +46,16 @@ impl XcbConnection {
|
|||
|
||||
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 {
|
||||
conn,
|
||||
xlib_display,
|
||||
|
||||
atoms: Atoms {
|
||||
wm_protocols,
|
||||
wm_delete_window,
|
||||
wm_normal_hints,
|
||||
},
|
||||
atoms: Atoms { 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() {
|
||||
let db = XrmGetStringDatabase(rms);
|
||||
if !db.is_null() {
|
||||
let mut value = XrmValue {
|
||||
size: 0,
|
||||
addr: std::ptr::null_mut(),
|
||||
};
|
||||
let mut value = XrmValue { size: 0, addr: 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();
|
||||
|
@ -144,16 +136,13 @@ impl XcbConnection {
|
|||
|
||||
#[inline]
|
||||
pub fn get_scaling(&self) -> Option<f64> {
|
||||
self.get_scaling_xft()
|
||||
.or(self.get_scaling_screen_dimensions())
|
||||
self.get_scaling_xft().or(self.get_scaling_screen_dimensions())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_cursor_xid(&mut self, cursor: MouseCursor) -> u32 {
|
||||
let dpy = self.conn.get_raw_dpy();
|
||||
|
||||
*self.cursor_cache
|
||||
.entry(cursor)
|
||||
.or_insert_with(|| cursor::get_xcursor(dpy, cursor))
|
||||
*self.cursor_cache.entry(cursor).or_insert_with(|| cursor::get_xcursor(dpy, cursor))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue