feat(wayland): shortcut inhibit
This commit is contained in:
parent
8e7b7e586f
commit
54a69a0523
11 changed files with 360 additions and 8 deletions
|
|
@ -0,0 +1,13 @@
|
|||
use iced_runtime::{
|
||||
self,
|
||||
platform_specific::{self, wayland},
|
||||
task, Action, Task,
|
||||
};
|
||||
|
||||
pub fn inhibit_shortcuts(inhibit: bool) -> Task<()> {
|
||||
task::oneshot(|_| {
|
||||
Action::PlatformSpecific(platform_specific::Action::Wayland(
|
||||
wayland::Action::InhibitShortcuts(inhibit),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
//! Interact with the wayland objects of your application.
|
||||
|
||||
pub mod activation;
|
||||
pub mod keyboard_shortcuts_inhibit;
|
||||
pub mod layer_surface;
|
||||
pub mod overlap_notify;
|
||||
pub mod popup;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ use std::{
|
|||
use tracing::error;
|
||||
use wayland_backend::client::Backend;
|
||||
use wayland_client::globals::GlobalError;
|
||||
use wayland_protocols::wp::keyboard_shortcuts_inhibit::zv1::client::zwp_keyboard_shortcuts_inhibit_manager_v1;
|
||||
use winit::{dpi::LogicalSize, event_loop::OwnedDisplayHandle};
|
||||
|
||||
use self::state::SctkState;
|
||||
|
|
@ -309,11 +310,19 @@ impl SctkEventLoop {
|
|||
®istry_state,
|
||||
&qh,
|
||||
),
|
||||
inhibitor_manager: registry_state.bind_one::<zwp_keyboard_shortcuts_inhibit_manager_v1::ZwpKeyboardShortcutsInhibitManagerV1, _, _>(
|
||||
&qh,
|
||||
1..=1,
|
||||
(),
|
||||
).ok(),
|
||||
registry_state,
|
||||
|
||||
queue_handle: qh,
|
||||
loop_handle,
|
||||
|
||||
|
||||
inhibitor: None,
|
||||
inhibited: false,
|
||||
_cursor_surface: None,
|
||||
_multipool: None,
|
||||
outputs: Vec::new(),
|
||||
|
|
@ -323,7 +332,6 @@ impl SctkEventLoop {
|
|||
popups: Vec::new(),
|
||||
lock_surfaces: Vec::new(),
|
||||
subsurfaces: Vec::new(),
|
||||
_kbd_focus: None,
|
||||
touch_points: HashMap::new(),
|
||||
sctk_events: Vec::new(),
|
||||
frame_status: HashMap::new(),
|
||||
|
|
|
|||
|
|
@ -94,8 +94,7 @@ use cctk::{cosmic_protocols::overlap_notify::v1::client::zcosmic_overlap_notific
|
|||
}, toplevel_info::ToplevelInfoState, toplevel_management::ToplevelManagerState};
|
||||
use wayland_protocols::{
|
||||
wp::{
|
||||
fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1,
|
||||
viewporter::client::wp_viewport::WpViewport,
|
||||
fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1, keyboard_shortcuts_inhibit::zv1::client::{zwp_keyboard_shortcuts_inhibit_manager_v1, zwp_keyboard_shortcuts_inhibitor_v1}, viewporter::client::wp_viewport::WpViewport
|
||||
},
|
||||
xdg::shell::client::xdg_surface::XdgSurface,
|
||||
};
|
||||
|
|
@ -388,7 +387,6 @@ pub struct SctkState {
|
|||
pub(crate) popups: Vec<SctkPopup>,
|
||||
pub(crate) subsurfaces: Vec<SctkSubsurface>,
|
||||
pub(crate) lock_surfaces: Vec<SctkLockSurface>,
|
||||
pub(crate) _kbd_focus: Option<WlSurface>,
|
||||
pub(crate) touch_points: HashMap<touch::Finger, (WlSurface, Point)>,
|
||||
|
||||
/// Window updates, which are coming from SCTK or the compositor, which require
|
||||
|
|
@ -434,6 +432,10 @@ pub struct SctkState {
|
|||
|
||||
pub(crate) activation_token_ctr: u32,
|
||||
pub(crate) token_senders: HashMap<u32, oneshot::Sender<Option<String>>>,
|
||||
|
||||
pub(crate) inhibitor: Option<zwp_keyboard_shortcuts_inhibitor_v1::ZwpKeyboardShortcutsInhibitorV1>,
|
||||
pub(crate) inhibited: bool,
|
||||
pub(crate) inhibitor_manager: Option<zwp_keyboard_shortcuts_inhibit_manager_v1::ZwpKeyboardShortcutsInhibitManagerV1>,
|
||||
}
|
||||
|
||||
/// An error that occurred while running an application.
|
||||
|
|
@ -1463,6 +1465,17 @@ impl SctkState {
|
|||
}
|
||||
},
|
||||
},
|
||||
Action::InhibitShortcuts(v) => {
|
||||
if let Some(manager) = self.inhibitor_manager.as_ref() {
|
||||
if let Some(inhibit) = self.inhibitor.take() {
|
||||
inhibit.destroy();
|
||||
}
|
||||
if v {
|
||||
self.inhibitor = self.seats.iter().next()
|
||||
.and_then(|s| s.kbd_focus.as_ref().map(|surface| manager.inhibit_shortcuts(surface, &s.seat, &self.queue_handle, ())));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
use cctk::sctk;
|
||||
use sctk::reexports::{
|
||||
client::{Connection, Dispatch, Proxy},
|
||||
protocols::wp::keyboard_shortcuts_inhibit::{
|
||||
self, zv1::client::zwp_keyboard_shortcuts_inhibitor_v1,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::event_loop::state::SctkState;
|
||||
use crate::platform_specific::wayland::SctkEvent;
|
||||
|
||||
impl Dispatch<keyboard_shortcuts_inhibit::zv1::client::zwp_keyboard_shortcuts_inhibit_manager_v1::ZwpKeyboardShortcutsInhibitManagerV1, ()> for SctkState {
|
||||
fn event(
|
||||
_state: &mut Self,
|
||||
_proxy: &keyboard_shortcuts_inhibit::zv1::client::zwp_keyboard_shortcuts_inhibit_manager_v1::ZwpKeyboardShortcutsInhibitManagerV1,
|
||||
_event: <keyboard_shortcuts_inhibit::zv1::client::zwp_keyboard_shortcuts_inhibit_manager_v1::ZwpKeyboardShortcutsInhibitManagerV1 as Proxy>::Event,
|
||||
_data: &(),
|
||||
_conn: &Connection,
|
||||
_qhandle: &sctk::reexports::client::QueueHandle<Self>,
|
||||
) {}
|
||||
}
|
||||
|
||||
impl
|
||||
Dispatch<
|
||||
zwp_keyboard_shortcuts_inhibitor_v1::ZwpKeyboardShortcutsInhibitorV1,
|
||||
(),
|
||||
> for SctkState
|
||||
{
|
||||
fn event(
|
||||
state: &mut Self,
|
||||
_proxy: &zwp_keyboard_shortcuts_inhibitor_v1::ZwpKeyboardShortcutsInhibitorV1,
|
||||
event: <zwp_keyboard_shortcuts_inhibitor_v1::ZwpKeyboardShortcutsInhibitorV1 as Proxy>::Event,
|
||||
_data: &(),
|
||||
_conn: &Connection,
|
||||
_qhandle: &sctk::reexports::client::QueueHandle<Self>,
|
||||
) {
|
||||
match event {
|
||||
zwp_keyboard_shortcuts_inhibitor_v1::Event::Active => {
|
||||
state.sctk_events.push(SctkEvent::ShortcutsInhibited(true));
|
||||
state.inhibited = true;
|
||||
}
|
||||
zwp_keyboard_shortcuts_inhibitor_v1::Event::Inactive => {
|
||||
state.sctk_events.push(SctkEvent::ShortcutsInhibited(false));
|
||||
state.inhibited = false;
|
||||
if let Some(inhibitor) = state.inhibitor.take() {
|
||||
inhibitor.destroy();
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
// TODO support multi-seat handling
|
||||
pub mod keyboard;
|
||||
pub mod keyboard_shortcuts_inhibit;
|
||||
pub mod pointer;
|
||||
pub mod seat;
|
||||
pub mod touch;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// Borrowed from winit
|
||||
use iced_runtime::keyboard::{Key, Location, key::Named};
|
||||
use winit::keyboard::{KeyCode, NativeKeyCode, PhysicalKey};
|
||||
|
||||
/// Map the raw X11-style keycode to the `KeyCode` enum.
|
||||
///
|
||||
/// X11-style keycodes are offset by 8 from the keycodes the Linux kernel uses.
|
||||
|
|
@ -838,8 +840,6 @@ pub fn keysym_to_key(keysym: u32) -> Key {
|
|||
})
|
||||
}
|
||||
|
||||
use iced_runtime::keyboard::{Key, Location, key::Named};
|
||||
|
||||
pub fn keysym_location(keysym: u32) -> Location {
|
||||
use xkbcommon_dl::keysyms;
|
||||
match keysym {
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ pub enum SctkEvent {
|
|||
SurfaceScaleFactorChanged(f64, WlSurface, window::Id),
|
||||
Winit(WindowId, WindowEvent),
|
||||
Subcompositor(SubsurfaceState),
|
||||
ShortcutsInhibited(bool),
|
||||
}
|
||||
|
||||
#[cfg(feature = "a11y")]
|
||||
|
|
@ -1697,6 +1698,14 @@ impl SctkEvent {
|
|||
}
|
||||
}
|
||||
},
|
||||
SctkEvent::ShortcutsInhibited(v) => events.push((
|
||||
None,
|
||||
iced_runtime::core::Event::PlatformSpecific(
|
||||
PlatformSpecific::Wayland(
|
||||
wayland::Event::ShortcutsInhibited(v),
|
||||
),
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue