Skip to content

Commit

Permalink
Update SCTK to 0.18.0
Browse files Browse the repository at this point in the history
The update is pretty minor, however we support now
`WindowEvent::Occluded` when xdg-shell v6 is available.

It also adds support for `Window::show_window_menu`.

Fixes #2927.
  • Loading branch information
kchibisov committed Oct 12, 2023
1 parent 93f1000 commit 480c55e
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 155 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ And please only add new entries to the top of this list, right below the `# Unre
- On Android, fix `DeviceId` to contain device id's.
- Add `Window::set_blur` to request a blur behind the window; implemented on Wayland for now.
- On Web, fix `ControlFlow::WaitUntil` to never wake up **before** the given time.
- Add `Window::show_window_menu` to request a titlebar/system menu; implemented on Windows for now.
- Add `Window::show_window_menu` to request a titlebar/system menu; implemented on Wayland/Windows for now.
- On Wayland, support `Occluded` event with xdg-shell v6

# 0.29.1-beta

Expand Down
18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -141,21 +141,21 @@ features = [

[target.'cfg(all(unix, not(any(target_os = "redox", target_family = "wasm", target_os = "android", target_os = "ios", target_os = "macos"))))'.dependencies]
bytemuck = { version = "1.13.1", default-features = false, optional = true }
calloop = "0.12.3"
fnv = { version = "1.0.3", optional = true }
libc = "0.2.64"
memmap2 = { version = "0.9.0", optional = true }
percent-encoding = { version = "2.0", optional = true }
fnv = { version = "1.0.3", optional = true }
sctk = { package = "smithay-client-toolkit", version = "0.17.0", default-features = false, features = ["calloop"], optional = true }
sctk-adwaita = { version = "0.6.0", default_features = false, optional = true }
wayland-client = { version = "0.30.0", optional = true }
wayland-backend = { version = "0.1.0", default_features = false, features = ["client_system"], optional = true }
wayland-protocols = { version = "0.30.0", features = [ "staging"], optional = true }
wayland-protocols-plasma = { version = "0.1.0", features = [ "client" ], optional = true }
calloop = "0.10.5"
rustix = { version = "0.38.4", default-features = false, features = ["std", "system", "thread", "process"] }
sctk = { package = "smithay-client-toolkit", version = "0.18.0", default-features = false, features = ["calloop"], optional = true }
sctk-adwaita = { git = "https://github.com/kchibisov/sctk-adwaita", branch = "wayland-csd-frame", default_features = false, optional = true }
wayland-backend = { version = "0.3.0", default_features = false, features = ["client_system"], optional = true }
wayland-client = { version = "0.31.1", optional = true }
wayland-protocols = { version = "0.31.0", features = [ "staging"], optional = true }
wayland-protocols-plasma = { version = "0.2.0", features = [ "client" ], optional = true }
x11-dl = { version = "2.18.5", optional = true }
x11rb = { version = "0.12.0", default-features = false, features = ["allow-unsafe-code", "dl-libxcb", "randr", "resource_manager", "xinput", "xkb"], optional = true }
xkbcommon-dl = "0.4.0"
memmap2 = { version = "0.5.0", optional = true }

[target.'cfg(target_os = "redox")'.dependencies]
orbclient = { version = "0.3.42", default-features = false }
Expand Down
2 changes: 0 additions & 2 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ deny = []
skip = [
{ name = "bitflags" }, # the ecosystem is in the process of migrating.
{ name = "nix" }, # differing version - as of 2023-03-02 whis can be solved with `cargo update && cargo update -p calloop --precise 0.10.2`
{ name = "memoffset"}, # due to different nix versions.
{ name = "memmap2" }, # sctk uses a different version until the next update
{ name = "libloading" }, # x11rb uses a different version until the next update
{ name = "syn" }, # https://github.com/rust-mobile/ndk/issues/392
{ name = "num_enum"}, # See above ^, waiting for release
Expand Down
2 changes: 1 addition & 1 deletion src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ pub enum WindowEvent {
/// ### Others
///
/// - **Web:** Doesn't take into account CSS [`border`], [`padding`], or [`transform`].
/// - **Android / Wayland / Windows / Orbital:** Unsupported.
/// - **Android / Windows / Orbital:** Unsupported.
///
/// [`border`]: https://developer.mozilla.org/en-US/docs/Web/CSS/border
/// [`padding`]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/linux/common/xkb_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use xkbcommon_dl::{
XkbCommonCompose,
};
#[cfg(feature = "wayland")]
use {memmap2::MmapOptions, wayland_backend::io_lifetimes::OwnedFd};
use {memmap2::MmapOptions, std::os::unix::io::OwnedFd};
#[cfg(feature = "x11")]
use {x11_dl::xlib_xcb::xcb_connection_t, xkbcommon_dl::x11::xkbcommon_x11_handle};

Expand Down
4 changes: 3 additions & 1 deletion src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,9 @@ impl Window {
}

#[inline]
pub fn show_window_menu(&self, _position: Position) {}
pub fn show_window_menu(&self, position: Position) {
x11_or_wayland!(match self; Window(w) => w.show_window_menu(position))
}

#[inline]
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
Expand Down
54 changes: 11 additions & 43 deletions src/platform_impl/linux/wayland/event_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};

use sctk::reexports::calloop;
use sctk::reexports::calloop::Error as CalloopError;
use sctk::reexports::calloop_wayland_source::WaylandSource;
use sctk::reexports::client::globals;
use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource};
use sctk::reexports::client::{Connection, Proxy, QueueHandle};

use crate::dpi::{LogicalSize, PhysicalSize};
use crate::error::{EventLoopError, OsError as RootOsError};
Expand Down Expand Up @@ -102,7 +103,7 @@ impl<T: 'static> EventLoop<T> {
)?;

// Register Wayland source.
let wayland_source = map_err!(WaylandSource::new(event_queue), WaylandError::Wire)?;
let wayland_source = WaylandSource::new(connection.clone(), event_queue);
let wayland_dispatcher =
calloop::Dispatcher::new(wayland_source, |_, queue, winit_state: &mut WinitState| {
let result = queue.dispatch_pending(winit_state);
Expand Down Expand Up @@ -254,46 +255,7 @@ impl<T: 'static> EventLoop<T> {
let cause = loop {
let start = Instant::now();

// TODO(rib): remove this workaround and instead make sure that the calloop
// WaylandSource correctly implements the cooperative prepare_read protocol
// that support multithreaded wayland clients that may all read from the
// same socket.
//
// During the run of the user callback, some other code monitoring and reading the
// Wayland socket may have been run (mesa for example does this with vsync), if that
// is the case, some events may have been enqueued in our event queue.
//
// If some messages are there, the event loop needs to behave as if it was instantly
// woken up by messages arriving from the Wayland socket, to avoid delaying the
// dispatch of these events until we're woken up again.
let instant_wakeup = {
let mut wayland_source = self.wayland_dispatcher.as_source_mut();
let queue = wayland_source.queue();
let state = match &mut self.window_target.p {
PlatformEventLoopWindowTarget::Wayland(window_target) => {
window_target.state.get_mut()
}
#[cfg(x11_platform)]
_ => unreachable!(),
};

match queue.dispatch_pending(state) {
Ok(dispatched) => {
state.dispatched_events |= !state.events_sink.is_empty()
|| !state.window_compositor_updates.is_empty();
dispatched > 0
}
Err(error) => {
error!("Error dispatching wayland queue: {}", error);
self.set_exit_code(1);
return;
}
}
};

timeout = if instant_wakeup {
Some(Duration::ZERO)
} else {
timeout = {
let control_flow_timeout = match self.control_flow() {
ControlFlow::Wait => None,
ControlFlow::Poll => Some(Duration::ZERO),
Expand All @@ -307,7 +269,13 @@ impl<T: 'static> EventLoop<T> {
// NOTE Ideally we should flush as the last thing we do before polling
// to wait for events, and this should be done by the calloop
// WaylandSource but we currently need to flush writes manually.
let _ = self.connection.flush();
//
// Checking for flush error is essential to perform an exit with error, since
// once we have a protocol error, we could get stuck retrying...
if self.connection.flush().is_err() {
self.set_exit_code(1);
return;
}

if let Err(error) = self.loop_dispatch(timeout) {
// NOTE We exit on errors from dispatches, since if we've got protocol error
Expand Down
15 changes: 13 additions & 2 deletions src/platform_impl/linux/wayland/seat/keyboard/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ impl Dispatch<WlKeyboard, KeyboardData, WinitState> for WinitState {
};

// Drop the repeat, if there were any.
seat_state.keyboard_state.as_mut().unwrap().current_repeat = None;
let keyboard_state = seat_state.keyboard_state.as_mut().unwrap();
keyboard_state.current_repeat = None;
if let Some(token) = keyboard_state.repeat_token.take() {
keyboard_state.loop_handle.remove(token);
}

// The keyboard focus is considered as general focus.
state
Expand All @@ -89,7 +93,11 @@ impl Dispatch<WlKeyboard, KeyboardData, WinitState> for WinitState {

// NOTE: we should drop the repeat regardless whethere it was for the present
// window of for the window which just went gone.
seat_state.keyboard_state.as_mut().unwrap().current_repeat = None;
let keyboard_state = seat_state.keyboard_state.as_mut().unwrap();
keyboard_state.current_repeat = None;
if let Some(token) = keyboard_state.repeat_token.take() {
keyboard_state.loop_handle.remove(token);
}

// NOTE: The check whether the window exists is essential as we might get a
// nil surface, regardless of what protocol says.
Expand Down Expand Up @@ -204,6 +212,9 @@ impl Dispatch<WlKeyboard, KeyboardData, WinitState> for WinitState {
&& Some(key) == keyboard_state.current_repeat
{
keyboard_state.current_repeat = None;
if let Some(token) = keyboard_state.repeat_token.take() {
keyboard_state.loop_handle.remove(token);
}
}
}
WlKeyboardEvent::Modifiers {
Expand Down
19 changes: 6 additions & 13 deletions src/platform_impl/linux/wayland/seat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use keyboard::{KeyboardData, KeyboardState};
use text_input::TextInputData;
use touch::TouchPoint;

#[derive(Debug)]
#[derive(Debug, Default)]
pub struct WinitSeatState {
/// The pointer bound on the seat.
pointer: Option<Arc<ThemedPointer<WinitPointerData>>>,
Expand Down Expand Up @@ -58,16 +58,7 @@ pub struct WinitSeatState {

impl WinitSeatState {
pub fn new() -> Self {
Self {
pointer: None,
touch: None,
relative_pointer: None,
text_input: None,
touch_map: Default::default(),
keyboard_state: None,
modifiers: ModifiersState::empty(),
modifiers_pending: false,
}
Default::default()
}
}

Expand Down Expand Up @@ -97,12 +88,14 @@ impl SeatHandler for WinitState {
SeatCapability::Pointer if seat_state.pointer.is_none() => {
let surface = self.compositor_state.create_surface(queue_handle);
let surface_id = surface.id();
let pointer_data = WinitPointerData::new(seat.clone(), surface);
let pointer_data = WinitPointerData::new(seat.clone());
let themed_pointer = self
.seat_state
.get_pointer_with_theme_and_data(
queue_handle,
&seat,
self.shm.wl_shm(),
surface,
ThemeSpec::System,
pointer_data,
)
Expand Down Expand Up @@ -167,7 +160,7 @@ impl SeatHandler for WinitState {
let pointer_data = pointer.pointer().winit_data();

// Remove the cursor from the mapping.
let surface_id = pointer_data.cursor_surface().id();
let surface_id = pointer.surface().id();
let _ = self.pointer_surfaces.remove(&surface_id);

// Remove the inner locks/confines before dropping the pointer.
Expand Down
Loading

0 comments on commit 480c55e

Please sign in to comment.