Skip to content

Commit

Permalink
Upgrade to smithay-client-toolkit 0.4 (#671)
Browse files Browse the repository at this point in the history
* Upgrade to smithay-client-toolkit 0.4

* Fix PR points
  • Loading branch information
trimental authored and francesca64 committed Oct 14, 2018
1 parent 808638f commit 50008df
Show file tree
Hide file tree
Showing 7 changed files with 314 additions and 287 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Unreleased

- On Wayland, titles will now be displayed in the window header decoration
- On Wayland, key repetition is now ended when keyboard loses focus
- On Wayland, windows will now use more stylish and modern client side decorations.
- On Wayland, windows will use server-side decorations when available.
- Added support for F16-F24 keys.
- Fixed graphical glitches when resizing on Wayland.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ features = [
]

[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
wayland-client = { version = "0.20.10", features = [ "dlopen", "egl", "cursor"] }
smithay-client-toolkit = "0.3.0"
wayland-client = { version = "0.21", features = [ "dlopen", "egl", "cursor"] }
smithay-client-toolkit = "0.4"
x11-dl = "2.18.3"
parking_lot = "0.6"
percent-encoding = "1.0"
63 changes: 35 additions & 28 deletions src/platform/linux/wayland/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use super::window::WindowStore;
use super::WindowId;

use sctk::output::OutputMgr;
use sctk::reexports::client::commons::Implementation;
use sctk::reexports::client::protocol::{
wl_keyboard, wl_output, wl_pointer, wl_registry, wl_seat, wl_touch,
};
Expand Down Expand Up @@ -93,7 +92,7 @@ impl EventsLoopProxy {
// Update the `EventsLoop`'s `pending_wakeup` flag.
wakeup.store(true, Ordering::Relaxed);
// Cause the `EventsLoop` to break from `dispatch` if it is currently blocked.
let _ = display.sync();
let _ = display.sync(|callback| callback.implement(|_, _| {}, ()));
display.flush().map_err(|_| EventsLoopClosed)?;
Ok(())
}
Expand All @@ -112,17 +111,21 @@ impl EventsLoop {
let store = Arc::new(Mutex::new(WindowStore::new()));
let seats = Arc::new(Mutex::new(Vec::new()));

let env = Environment::from_registry_with_cb(
display.get_registry().unwrap(),
let mut seat_manager = SeatManager {
sink: sink.clone(),
store: store.clone(),
seats: seats.clone(),
events_loop_proxy: EventsLoopProxy {
display: Arc::downgrade(&display),
pending_wakeup: Arc::downgrade(&pending_wakeup),
},
};

let env = Environment::from_display_with_cb(
&display,
&mut event_queue,
SeatManager {
sink: sink.clone(),
store: store.clone(),
seats: seats.clone(),
events_loop_proxy: EventsLoopProxy {
display: Arc::downgrade(&display),
pending_wakeup: Arc::downgrade(&pending_wakeup),
},
move |event, registry| {
seat_manager.receive(event, registry)
},
).unwrap();

Expand Down Expand Up @@ -280,7 +283,7 @@ struct SeatManager {
events_loop_proxy: EventsLoopProxy,
}

impl Implementation<Proxy<wl_registry::WlRegistry>, GlobalEvent> for SeatManager {
impl SeatManager {
fn receive(&mut self, evt: GlobalEvent, registry: Proxy<wl_registry::WlRegistry>) {
use self::wl_registry::RequestsTrait as RegistryRequests;
use self::wl_seat::RequestsTrait as SeatRequests;
Expand All @@ -292,17 +295,22 @@ impl Implementation<Proxy<wl_registry::WlRegistry>, GlobalEvent> for SeatManager
} if interface == "wl_seat" =>
{
use std::cmp::min;

let mut seat_data = SeatData {
sink: self.sink.clone(),
store: self.store.clone(),
pointer: None,
keyboard: None,
touch: None,
events_loop_proxy: self.events_loop_proxy.clone(),
};
let seat = registry
.bind::<wl_seat::WlSeat>(min(version, 5), id)
.unwrap()
.implement(SeatData {
sink: self.sink.clone(),
store: self.store.clone(),
pointer: None,
keyboard: None,
touch: None,
events_loop_proxy: self.events_loop_proxy.clone(),
});
.bind(min(version, 5), id, move |seat| {
seat.implement(move |event, seat| {
seat_data.receive(event, seat)
}, ())
})
.unwrap();
self.store.lock().unwrap().new_seat(&seat);
self.seats.lock().unwrap().push((id, seat));
}
Expand All @@ -329,16 +337,15 @@ struct SeatData {
events_loop_proxy: EventsLoopProxy,
}

impl Implementation<Proxy<wl_seat::WlSeat>, wl_seat::Event> for SeatData {
impl SeatData {
fn receive(&mut self, evt: wl_seat::Event, seat: Proxy<wl_seat::WlSeat>) {
use self::wl_seat::RequestsTrait as SeatRequests;
match evt {
wl_seat::Event::Name { .. } => (),
wl_seat::Event::Capabilities { capabilities } => {
// create pointer if applicable
if capabilities.contains(wl_seat::Capability::Pointer) && self.pointer.is_none() {
self.pointer = Some(super::pointer::implement_pointer(
seat.get_pointer().unwrap(),
&seat,
self.sink.clone(),
self.store.clone(),
))
Expand All @@ -355,7 +362,7 @@ impl Implementation<Proxy<wl_seat::WlSeat>, wl_seat::Event> for SeatData {
// create keyboard if applicable
if capabilities.contains(wl_seat::Capability::Keyboard) && self.keyboard.is_none() {
self.keyboard = Some(super::keyboard::init_keyboard(
seat.get_keyboard().unwrap(),
&seat,
self.sink.clone(),
self.events_loop_proxy.clone(),
))
Expand All @@ -372,7 +379,7 @@ impl Implementation<Proxy<wl_seat::WlSeat>, wl_seat::Event> for SeatData {
// create touch if applicable
if capabilities.contains(wl_seat::Capability::Touch) && self.touch.is_none() {
self.touch = Some(super::touch::implement_touch(
seat.get_touch().unwrap(),
&seat,
self.sink.clone(),
self.store.clone(),
))
Expand Down
97 changes: 53 additions & 44 deletions src/platform/linux/wayland/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ use sctk::keyboard::{
self, map_keyboard_auto_with_repeat, Event as KbEvent, KeyRepeatEvent, KeyRepeatKind,
};
use sctk::reexports::client::protocol::wl_keyboard;
use sctk::reexports::client::{NewProxy, Proxy};
use sctk::reexports::client::Proxy;
use sctk::reexports::client::protocol::wl_seat;
use sctk::reexports::client::protocol::wl_seat::RequestsTrait as SeatRequests;

use {ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent};

pub fn init_keyboard(
keyboard: NewProxy<wl_keyboard::WlKeyboard>,
seat: &Proxy<wl_seat::WlSeat>,
sink: Arc<Mutex<EventsLoopSink>>,
events_loop_proxy: EventsLoopProxy,
) -> Proxy<wl_keyboard::WlKeyboard> {
Expand All @@ -18,9 +21,11 @@ pub fn init_keyboard(
let my_sink = sink.clone();
let repeat_sink = sink.clone();
let repeat_target = target.clone();
let modifiers = Arc::new(Mutex::new(ModifiersState::default()));
let my_modifiers = modifiers.clone();
// }
let ret = map_keyboard_auto_with_repeat(
keyboard,
seat,
KeyRepeatKind::System,
move |evt: KbEvent, _| match evt {
KbEvent::Enter { surface, .. } => {
Expand All @@ -40,7 +45,6 @@ pub fn init_keyboard(
*target.lock().unwrap() = None;
}
KbEvent::Key {
modifiers,
rawkey,
keysym,
state,
Expand All @@ -61,7 +65,7 @@ pub fn init_keyboard(
state: state,
scancode: rawkey,
virtual_keycode: vkcode,
modifiers: modifiers.into(),
modifiers: modifiers.lock().unwrap().clone(),
},
},
wid,
Expand All @@ -78,6 +82,9 @@ pub fn init_keyboard(
}
}
KbEvent::RepeatInfo { .. } => { /* Handled by smithay client toolkit */ }
KbEvent::Modifiers { modifiers: event_modifiers } => {
*modifiers.lock().unwrap() = event_modifiers.into()
}
},
move |repeat_event: KeyRepeatEvent, _| {
if let Some(wid) = *repeat_target.lock().unwrap() {
Expand All @@ -91,7 +98,7 @@ pub fn init_keyboard(
state: state,
scancode: repeat_event.rawkey,
virtual_keycode: vkcode,
modifiers: repeat_event.modifiers.into(),
modifiers: my_modifiers.lock().unwrap().clone(),
},
},
wid,
Expand All @@ -108,7 +115,7 @@ pub fn init_keyboard(

match ret {
Ok(keyboard) => keyboard,
Err((_, keyboard)) => {
Err(_) => {
// This is a fallback impl if libxkbcommon was not available
// This case should probably never happen, as most wayland
// compositors _need_ libxkbcommon anyway...
Expand All @@ -120,45 +127,47 @@ pub fn init_keyboard(
let mut target = None;
let my_sink = sink;
// }
keyboard.implement(move |evt, _| match evt {
wl_keyboard::Event::Enter { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(true), wid);
target = Some(wid);
}
wl_keyboard::Event::Leave { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(false), wid);
target = None;
}
wl_keyboard::Event::Key { key, state, .. } => {
if let Some(wid) = target {
let state = match state {
wl_keyboard::KeyState::Pressed => ElementState::Pressed,
wl_keyboard::KeyState::Released => ElementState::Released,
};
my_sink.lock().unwrap().send_event(
WindowEvent::KeyboardInput {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
input: KeyboardInput {
state: state,
scancode: key,
virtual_keycode: None,
modifiers: ModifiersState::default(),
seat.get_keyboard(|keyboard| {
keyboard.implement(move |evt, _| match evt {
wl_keyboard::Event::Enter { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(true), wid);
target = Some(wid);
}
wl_keyboard::Event::Leave { surface, .. } => {
let wid = make_wid(&surface);
my_sink
.lock()
.unwrap()
.send_event(WindowEvent::Focused(false), wid);
target = None;
}
wl_keyboard::Event::Key { key, state, .. } => {
if let Some(wid) = target {
let state = match state {
wl_keyboard::KeyState::Pressed => ElementState::Pressed,
wl_keyboard::KeyState::Released => ElementState::Released,
};
my_sink.lock().unwrap().send_event(
WindowEvent::KeyboardInput {
device_id: ::DeviceId(::platform::DeviceId::Wayland(DeviceId)),
input: KeyboardInput {
state: state,
scancode: key,
virtual_keycode: None,
modifiers: ModifiersState::default(),
},
},
},
wid,
);
wid,
);
}
}
}
_ => (),
})
_ => (),
}, ())
}).unwrap()
}
}
}
Expand Down
Loading

0 comments on commit 50008df

Please sign in to comment.