Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/platform/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl MonitorId {
pub fn get_hidpi_factor(&self) -> f32 {
match self {
&MonitorId::X(ref m) => m.get_hidpi_factor(),
&MonitorId::Wayland(ref m) => m.get_hidpi_factor(),
&MonitorId::Wayland(ref m) => m.get_hidpi_factor() as f32,
}
}
}
Expand Down
43 changes: 37 additions & 6 deletions src/platform/linux/wayland/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,16 +250,47 @@ impl EventsLoop {
}
// process pending resize/refresh
self.store.lock().unwrap().for_each(
|newsize, refresh, frame_refresh, closed, wid, frame| {
|newsize, size, current_dpi, new_dpi, refresh, frame_refresh, closed, wid, frame| {
// update frame if needed
if let Some(frame) = frame {
if let Some((w, h)) = newsize {
frame.resize(w as u32, h as u32);
frame.resize(w, h);
frame.refresh();
sink.send_event(::WindowEvent::Resized(w as u32, h as u32), wid);
*size = (w, h);
} else if frame_refresh {
frame.refresh();
}
}
// handle dpi/size change
match (newsize, new_dpi) {
(Some((w, h)), Some(new_dpi)) => {
// both size and dpi changed, compute a compound event
let dpi_w = w * new_dpi as u32;
let dpi_h = h * new_dpi as u32;
sink.send_event(::WindowEvent::HiDPIFactorChanged(new_dpi as f32), wid);
sink.send_event(::WindowEvent::Resized(dpi_w as u32, dpi_h as u32), wid);
*size = (dpi_w as u32, dpi_h as u32);
},
(None, Some(new_dpi)) => {
// dpi has changed, fetch previous DPI-aware size and recompute it
let (old_w, old_h) = *size;
let dpi_w = old_w as i32 * new_dpi / current_dpi;
let dpi_h = old_h as i32 * new_dpi / current_dpi;
sink.send_event(::WindowEvent::HiDPIFactorChanged(new_dpi as f32), wid);
sink.send_event(::WindowEvent::Resized(dpi_w as u32, dpi_h as u32), wid);
*size = (dpi_w as u32, dpi_h as u32);
},
(Some((w, h)), None) => {
// new size, take dpi into account to send resized event
let dpi_w = w * current_dpi as u32;
let dpi_h = h * current_dpi as u32;
sink.send_event(::WindowEvent::Resized(dpi_w as u32, dpi_h as u32), wid);
*size = (dpi_w as u32, dpi_h as u32);
},
(None, None) => {
// nothing to do
}
}
if refresh {
sink.send_event(::WindowEvent::Refresh, wid);
}
Expand Down Expand Up @@ -461,9 +492,9 @@ impl MonitorId {
}

#[inline]
pub fn get_hidpi_factor(&self) -> f32 {
pub fn get_hidpi_factor(&self) -> i32 {
self.mgr
.with_info(&self.proxy, |_, info| info.scale_factor as f32)
.unwrap_or(1.0)
.with_info(&self.proxy, |_, info| info.scale_factor)
.unwrap_or(1)
}
}
74 changes: 35 additions & 39 deletions src/platform/linux/wayland/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex};
use {ElementState, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent};
use events::ModifiersState;

use super::DeviceId;
use super::{DeviceId, make_wid};
use super::event_loop::EventsLoopSink;
use super::window::WindowStore;

Expand All @@ -30,57 +30,53 @@ pub fn implement_pointer(
surface_y,
..
} => {
let wid = store.find_wid(&surface);
if let Some(wid) = wid {
mouse_focus = Some(wid);
sink.send_event(
WindowEvent::CursorEntered {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
},
wid,
);
sink.send_event(
WindowEvent::CursorMoved {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
position: (surface_x, surface_y),
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid,
);
}
let dpi = store.get_dpi(&surface) as f64;
sink.send_event(
WindowEvent::CursorEntered {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
},
make_wid(&surface),
);
sink.send_event(
WindowEvent::CursorMoved {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
position: (dpi*surface_x, dpi*surface_y),
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
make_wid(&surface),
);
mouse_focus = Some(surface);
}
PtrEvent::Leave { surface, .. } => {
mouse_focus = None;
let wid = store.find_wid(&surface);
if let Some(wid) = wid {
sink.send_event(
WindowEvent::CursorLeft {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
},
wid,
);
}
sink.send_event(
WindowEvent::CursorLeft {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
},
make_wid(&surface),
);
}
PtrEvent::Motion {
surface_x,
surface_y,
..
} => {
if let Some(wid) = mouse_focus {
if let Some(ref surface) = mouse_focus {
let dpi = store.get_dpi(&surface) as f64;
sink.send_event(
WindowEvent::CursorMoved {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
position: (surface_x, surface_y),
position: (dpi*surface_x, dpi*surface_y),
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid,
make_wid(surface),
);
}
}
PtrEvent::Button { button, state, .. } => {
if let Some(wid) = mouse_focus {
if let Some(ref surface) = mouse_focus {
let state = match state {
wl_pointer::ButtonState::Pressed => ElementState::Pressed,
wl_pointer::ButtonState::Released => ElementState::Released,
Expand All @@ -100,12 +96,12 @@ pub fn implement_pointer(
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid,
make_wid(surface),
);
}
}
PtrEvent::Axis { axis, value, .. } => {
if let Some(wid) = mouse_focus {
if let Some(ref surface) = mouse_focus {
if pointer.version() < 5 {
let (mut x, mut y) = (0.0, 0.0);
// old seat compatibility
Expand All @@ -122,7 +118,7 @@ pub fn implement_pointer(
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid,
make_wid(surface),
);
} else {
let (mut x, mut y) = axis_buffer.unwrap_or((0.0, 0.0));
Expand All @@ -142,7 +138,7 @@ pub fn implement_pointer(
PtrEvent::Frame => {
let axis_buffer = axis_buffer.take();
let axis_discrete_buffer = axis_discrete_buffer.take();
if let Some(wid) = mouse_focus {
if let Some(ref surface) = mouse_focus {
if let Some((x, y)) = axis_discrete_buffer {
sink.send_event(
WindowEvent::MouseWheel {
Expand All @@ -152,7 +148,7 @@ pub fn implement_pointer(
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid,
make_wid(surface),
);
} else if let Some((x, y)) = axis_buffer {
sink.send_event(
Expand All @@ -163,7 +159,7 @@ pub fn implement_pointer(
// TODO: replace dummy value with actual modifier state
modifiers: ModifiersState::default(),
},
wid,
make_wid(surface),
);
}
}
Expand Down
49 changes: 25 additions & 24 deletions src/platform/linux/wayland/touch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ use std::sync::{Arc, Mutex};

use {TouchPhase, WindowEvent};

use super::{DeviceId, WindowId};
use super::{DeviceId, make_wid};
use super::event_loop::EventsLoopSink;
use super::window::WindowStore;

use sctk::reexports::client::{NewProxy, Proxy};
use sctk::reexports::client::protocol::wl_surface;
use sctk::reexports::client::protocol::wl_touch::{Event as TouchEvent, WlTouch};

struct TouchPoint {
wid: WindowId,
surface: Proxy<wl_surface::WlSurface>,
location: (f64, f64),
id: i32,
}
Expand All @@ -28,23 +29,22 @@ pub(crate) fn implement_touch(
TouchEvent::Down {
surface, id, x, y, ..
} => {
let wid = store.find_wid(&surface);
if let Some(wid) = wid {
sink.send_event(
WindowEvent::Touch(::Touch {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
phase: TouchPhase::Started,
location: (x, y),
id: id as u64,
}),
wid,
);
pending_ids.push(TouchPoint {
wid: wid,
location: (x, y),
id: id,
});
}
let dpi = store.get_dpi(&surface) as f64;
let location = (dpi*x, dpi*y);
sink.send_event(
WindowEvent::Touch(::Touch {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
phase: TouchPhase::Started,
location,
id: id as u64,
}),
make_wid(&surface),
);
pending_ids.push(TouchPoint {
surface: surface,
location,
id: id,
});
}
TouchEvent::Up { id, .. } => {
let idx = pending_ids.iter().position(|p| p.id == id);
Expand All @@ -57,22 +57,23 @@ pub(crate) fn implement_touch(
location: pt.location,
id: id as u64,
}),
pt.wid,
make_wid(&pt.surface),
);
}
}
TouchEvent::Motion { id, x, y, .. } => {
let pt = pending_ids.iter_mut().find(|p| p.id == id);
if let Some(pt) = pt {
pt.location = (x, y);
let dpi = store.get_dpi(&pt.surface) as f64;
pt.location = (dpi*x, dpi*y);
sink.send_event(
WindowEvent::Touch(::Touch {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
phase: TouchPhase::Moved,
location: (x, y),
location: pt.location,
id: id as u64,
}),
pt.wid,
make_wid(&pt.surface),
);
}
}
Expand All @@ -85,7 +86,7 @@ pub(crate) fn implement_touch(
location: pt.location,
id: pt.id as u64,
}),
pt.wid,
make_wid(&pt.surface),
);
},
}
Expand Down
Loading