mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Update Smithay (virtual keyboard, layer-shell geometry, GPU profiling)
Also includes the necessary code to handle the virtual keyboard compositor-side. Similar to the virtual pointer, we have an InputDevice impl that allows reusing the logic from process_input_event(). Co-authored-by: wxt <3264117476@qq.com>
This commit is contained in:
Generated
+2
-2
@@ -3397,7 +3397,7 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay"
|
name = "smithay"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "git+https://github.com/Smithay/smithay.git#ca932e042fa9ad150605c150a86275b85f9ad5b3"
|
source = "git+https://github.com/Smithay/smithay.git#2928e4f34541d957b7b3c3b3e13b2539cd44990f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aliasable",
|
"aliasable",
|
||||||
"appendlist",
|
"appendlist",
|
||||||
@@ -3471,7 +3471,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-drm-extras"
|
name = "smithay-drm-extras"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/Smithay/smithay.git#ca932e042fa9ad150605c150a86275b85f9ad5b3"
|
source = "git+https://github.com/Smithay/smithay.git#2928e4f34541d957b7b3c3b3e13b2539cd44990f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"drm",
|
"drm",
|
||||||
"libdisplay-info",
|
"libdisplay-info",
|
||||||
|
|||||||
+1
-2
@@ -68,7 +68,7 @@ use smithay::{
|
|||||||
delegate_pointer_gestures, delegate_presentation, delegate_primary_selection,
|
delegate_pointer_gestures, delegate_presentation, delegate_primary_selection,
|
||||||
delegate_relative_pointer, delegate_seat, delegate_security_context, delegate_session_lock,
|
delegate_relative_pointer, delegate_seat, delegate_security_context, delegate_session_lock,
|
||||||
delegate_single_pixel_buffer, delegate_tablet_manager, delegate_text_input_manager,
|
delegate_single_pixel_buffer, delegate_tablet_manager, delegate_text_input_manager,
|
||||||
delegate_viewporter, delegate_virtual_keyboard_manager, delegate_xdg_activation,
|
delegate_viewporter, delegate_xdg_activation,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::handlers::xdg_shell::KdeDecorationsModeState;
|
pub use crate::handlers::xdg_shell::KdeDecorationsModeState;
|
||||||
@@ -279,7 +279,6 @@ impl KeyboardShortcutsInhibitHandler for State {
|
|||||||
|
|
||||||
delegate_input_method_manager!(State);
|
delegate_input_method_manager!(State);
|
||||||
delegate_keyboard_shortcuts_inhibit!(State);
|
delegate_keyboard_shortcuts_inhibit!(State);
|
||||||
delegate_virtual_keyboard_manager!(State);
|
|
||||||
|
|
||||||
impl SelectionHandler for State {
|
impl SelectionHandler for State {
|
||||||
type SelectionUserData = Arc<[u8]>;
|
type SelectionUserData = Arc<[u8]>;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use smithay::backend::winit::WinitVirtualDevice;
|
|||||||
use smithay::output::Output;
|
use smithay::output::Output;
|
||||||
|
|
||||||
use crate::niri::State;
|
use crate::niri::State;
|
||||||
|
use crate::protocols::virtual_keyboard::VirtualKeyboard;
|
||||||
use crate::protocols::virtual_pointer::VirtualPointer;
|
use crate::protocols::virtual_pointer::VirtualPointer;
|
||||||
|
|
||||||
pub trait NiriInputBackend: input::InputBackend<Device = Self::NiriDevice> {
|
pub trait NiriInputBackend: input::InputBackend<Device = Self::NiriDevice> {
|
||||||
@@ -44,6 +45,12 @@ impl NiriInputDevice for WinitVirtualDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NiriInputDevice for VirtualKeyboard {
|
||||||
|
fn output(&self, _: &State) -> Option<Output> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl NiriInputDevice for VirtualPointer {
|
impl NiriInputDevice for VirtualPointer {
|
||||||
fn output(&self, _: &State) -> Option<Output> {
|
fn output(&self, _: &State) -> Option<Output> {
|
||||||
self.output().cloned()
|
self.output().cloned()
|
||||||
|
|||||||
+29
-3
@@ -7,7 +7,7 @@ use std::time::Duration;
|
|||||||
use calloop::timer::{TimeoutAction, Timer};
|
use calloop::timer::{TimeoutAction, Timer};
|
||||||
use input::event::gesture::GestureEventCoordinates as _;
|
use input::event::gesture::GestureEventCoordinates as _;
|
||||||
use niri_config::{
|
use niri_config::{
|
||||||
Action, Bind, Binds, Config, Key, ModKey, Modifiers, MruDirection, SwitchBinds, Trigger,
|
Action, Bind, Binds, Config, Key, ModKey, Modifiers, MruDirection, SwitchBinds, Trigger, Xkb,
|
||||||
};
|
};
|
||||||
use niri_ipc::LayoutSwitchTarget;
|
use niri_ipc::LayoutSwitchTarget;
|
||||||
use smithay::backend::input::{
|
use smithay::backend::input::{
|
||||||
@@ -48,6 +48,7 @@ use crate::dbus::freedesktop_a11y::KbMonBlock;
|
|||||||
use crate::layout::scrolling::ScrollDirection;
|
use crate::layout::scrolling::ScrollDirection;
|
||||||
use crate::layout::{ActivateWindow, LayoutElement as _};
|
use crate::layout::{ActivateWindow, LayoutElement as _};
|
||||||
use crate::niri::{CastTarget, PointerVisibility, State};
|
use crate::niri::{CastTarget, PointerVisibility, State};
|
||||||
|
use crate::protocols::virtual_keyboard::VirtualKeyboard;
|
||||||
use crate::ui::mru::{WindowMru, WindowMruUi};
|
use crate::ui::mru::{WindowMru, WindowMruUi};
|
||||||
use crate::ui::screenshot_ui::ScreenshotUi;
|
use crate::ui::screenshot_ui::ScreenshotUi;
|
||||||
use crate::utils::spawning::{spawn, spawn_sh};
|
use crate::utils::spawning::{spawn, spawn_sh};
|
||||||
@@ -360,11 +361,36 @@ impl State {
|
|||||||
.is_some_and(KeyboardShortcutsInhibitor::is_active)
|
.is_some_and(KeyboardShortcutsInhibitor::is_active)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_keyboard<I: InputBackend>(
|
fn on_keyboard<I: InputBackend + 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: I::KeyboardKeyEvent,
|
event: I::KeyboardKeyEvent,
|
||||||
consumed_by_a11y: &mut bool,
|
consumed_by_a11y: &mut bool,
|
||||||
) {
|
) where
|
||||||
|
I::Device: 'static,
|
||||||
|
{
|
||||||
|
// Reset the keymap when handling a physical keyboard after a virtual one.
|
||||||
|
if self.niri.reset_keymap {
|
||||||
|
let device = event.device();
|
||||||
|
let is_virtual_keyboard = (&device as &dyn Any)
|
||||||
|
.downcast_ref::<VirtualKeyboard>()
|
||||||
|
.is_some();
|
||||||
|
if !is_virtual_keyboard {
|
||||||
|
self.niri.reset_keymap = false;
|
||||||
|
|
||||||
|
let config = self.niri.config.borrow();
|
||||||
|
let xkb_config = config.input.keyboard.xkb.clone();
|
||||||
|
std::mem::drop(config);
|
||||||
|
|
||||||
|
if xkb_config != Xkb::default() {
|
||||||
|
self.set_xkb_config(xkb_config.to_xkb_config());
|
||||||
|
} else {
|
||||||
|
// Use locale1 settings if xkb config is unset.
|
||||||
|
let xkb = self.niri.xkb_from_locale1.clone().unwrap_or_default();
|
||||||
|
self.set_xkb_config(xkb.to_xkb_config());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mod_key = self.backend.mod_key(&self.niri.config.borrow());
|
let mod_key = self.backend.mod_key(&self.niri.config.borrow());
|
||||||
|
|
||||||
let serial = SERIAL_COUNTER.next_serial();
|
let serial = SERIAL_COUNTER.next_serial();
|
||||||
|
|||||||
+7
-1
@@ -331,6 +331,11 @@ pub struct Niri {
|
|||||||
/// Most recent XKB settings from org.freedesktop.locale1.
|
/// Most recent XKB settings from org.freedesktop.locale1.
|
||||||
pub xkb_from_locale1: Option<Xkb>,
|
pub xkb_from_locale1: Option<Xkb>,
|
||||||
|
|
||||||
|
/// Whether to reset the keymap on the next physical keyboard event.
|
||||||
|
///
|
||||||
|
/// Set to true when handling virtual keyboard events which override the keymap.
|
||||||
|
pub reset_keymap: bool,
|
||||||
|
|
||||||
pub cursor_manager: CursorManager,
|
pub cursor_manager: CursorManager,
|
||||||
pub cursor_texture_cache: CursorTextureCache,
|
pub cursor_texture_cache: CursorTextureCache,
|
||||||
pub cursor_shape_manager_state: CursorShapeManagerState,
|
pub cursor_shape_manager_state: CursorShapeManagerState,
|
||||||
@@ -1385,7 +1390,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_xkb_config(&mut self, xkb: XkbConfig) {
|
pub fn set_xkb_config(&mut self, xkb: XkbConfig) {
|
||||||
let keyboard = self.niri.seat.get_keyboard().unwrap();
|
let keyboard = self.niri.seat.get_keyboard().unwrap();
|
||||||
let num_lock = keyboard.modifier_state().num_lock;
|
let num_lock = keyboard.modifier_state().num_lock;
|
||||||
if let Err(err) = keyboard.set_xkb_config(self, xkb) {
|
if let Err(err) = keyboard.set_xkb_config(self, xkb) {
|
||||||
@@ -2505,6 +2510,7 @@ impl Niri {
|
|||||||
is_fdo_idle_inhibited: Arc::new(AtomicBool::new(false)),
|
is_fdo_idle_inhibited: Arc::new(AtomicBool::new(false)),
|
||||||
keyboard_shortcuts_inhibiting_surfaces: HashMap::new(),
|
keyboard_shortcuts_inhibiting_surfaces: HashMap::new(),
|
||||||
xkb_from_locale1: None,
|
xkb_from_locale1: None,
|
||||||
|
reset_keymap: false,
|
||||||
cursor_manager,
|
cursor_manager,
|
||||||
cursor_texture_cache: Default::default(),
|
cursor_texture_cache: Default::default(),
|
||||||
cursor_shape_manager_state,
|
cursor_shape_manager_state,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ pub mod gamma_control;
|
|||||||
pub mod mutter_x11_interop;
|
pub mod mutter_x11_interop;
|
||||||
pub mod output_management;
|
pub mod output_management;
|
||||||
pub mod screencopy;
|
pub mod screencopy;
|
||||||
|
pub mod virtual_keyboard;
|
||||||
pub mod virtual_pointer;
|
pub mod virtual_pointer;
|
||||||
|
|
||||||
pub mod raw;
|
pub mod raw;
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
use smithay::backend::input::{
|
||||||
|
Device, DeviceCapability, Event, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, Keycode,
|
||||||
|
UnusedEvent,
|
||||||
|
};
|
||||||
|
use smithay::delegate_virtual_keyboard_manager;
|
||||||
|
use smithay::input::keyboard::xkb::ModMask;
|
||||||
|
use smithay::input::keyboard::KeyboardHandle;
|
||||||
|
use smithay::wayland::virtual_keyboard::VirtualKeyboardHandler;
|
||||||
|
|
||||||
|
use crate::niri::State;
|
||||||
|
|
||||||
|
pub struct VirtualKeyboardInputBackend;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
|
pub struct VirtualKeyboard;
|
||||||
|
|
||||||
|
impl Device for VirtualKeyboard {
|
||||||
|
fn id(&self) -> String {
|
||||||
|
String::from("virtual keyboard")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String {
|
||||||
|
String::from("virtual keyboard")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_capability(&self, capability: DeviceCapability) -> bool {
|
||||||
|
matches!(capability, DeviceCapability::Keyboard)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usb_id(&self) -> Option<(u32, u32)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn syspath(&self) -> Option<std::path::PathBuf> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VirtualKeyboardKeyEvent {
|
||||||
|
pub keycode: Keycode,
|
||||||
|
pub state: KeyState,
|
||||||
|
pub time: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Event<VirtualKeyboardInputBackend> for VirtualKeyboardKeyEvent {
|
||||||
|
fn time(&self) -> u64 {
|
||||||
|
self.time as u64 * 1000 // millis to micros
|
||||||
|
}
|
||||||
|
|
||||||
|
fn device(&self) -> VirtualKeyboard {
|
||||||
|
VirtualKeyboard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyboardKeyEvent<VirtualKeyboardInputBackend> for VirtualKeyboardKeyEvent {
|
||||||
|
fn key_code(&self) -> Keycode {
|
||||||
|
self.keycode
|
||||||
|
}
|
||||||
|
|
||||||
|
fn state(&self) -> KeyState {
|
||||||
|
self.state
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count(&self) -> u32 {
|
||||||
|
0 // Not used by niri
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputBackend for VirtualKeyboardInputBackend {
|
||||||
|
type Device = VirtualKeyboard;
|
||||||
|
|
||||||
|
type KeyboardKeyEvent = VirtualKeyboardKeyEvent;
|
||||||
|
type PointerAxisEvent = UnusedEvent;
|
||||||
|
type PointerButtonEvent = UnusedEvent;
|
||||||
|
type PointerMotionEvent = UnusedEvent;
|
||||||
|
type PointerMotionAbsoluteEvent = UnusedEvent;
|
||||||
|
|
||||||
|
type GestureSwipeBeginEvent = UnusedEvent;
|
||||||
|
type GestureSwipeUpdateEvent = UnusedEvent;
|
||||||
|
type GestureSwipeEndEvent = UnusedEvent;
|
||||||
|
type GesturePinchBeginEvent = UnusedEvent;
|
||||||
|
type GesturePinchUpdateEvent = UnusedEvent;
|
||||||
|
type GesturePinchEndEvent = UnusedEvent;
|
||||||
|
type GestureHoldBeginEvent = UnusedEvent;
|
||||||
|
type GestureHoldEndEvent = UnusedEvent;
|
||||||
|
|
||||||
|
type TouchDownEvent = UnusedEvent;
|
||||||
|
type TouchUpEvent = UnusedEvent;
|
||||||
|
type TouchMotionEvent = UnusedEvent;
|
||||||
|
type TouchCancelEvent = UnusedEvent;
|
||||||
|
type TouchFrameEvent = UnusedEvent;
|
||||||
|
type TabletToolAxisEvent = UnusedEvent;
|
||||||
|
type TabletToolProximityEvent = UnusedEvent;
|
||||||
|
type TabletToolTipEvent = UnusedEvent;
|
||||||
|
type TabletToolButtonEvent = UnusedEvent;
|
||||||
|
|
||||||
|
type SwitchToggleEvent = UnusedEvent;
|
||||||
|
|
||||||
|
type SpecialEvent = UnusedEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtualKeyboardHandler for State {
|
||||||
|
fn on_keyboard_event(
|
||||||
|
&mut self,
|
||||||
|
keycode: Keycode,
|
||||||
|
state: KeyState,
|
||||||
|
time: u32,
|
||||||
|
_keyboard: KeyboardHandle<Self>,
|
||||||
|
) {
|
||||||
|
// The virtual keyboard impl in Smithay changes the keymap, so we'll need to reset it on
|
||||||
|
// the next real keyboard event.
|
||||||
|
self.niri.reset_keymap = true;
|
||||||
|
|
||||||
|
let event = VirtualKeyboardKeyEvent {
|
||||||
|
keycode,
|
||||||
|
state,
|
||||||
|
time,
|
||||||
|
};
|
||||||
|
self.process_input_event(InputEvent::<VirtualKeyboardInputBackend>::Keyboard { event });
|
||||||
|
}
|
||||||
|
|
||||||
|
// We handle modifiers when the key event is sent.
|
||||||
|
fn on_keyboard_modifiers(
|
||||||
|
&mut self,
|
||||||
|
_depressed_mods: ModMask,
|
||||||
|
_latched_mods: ModMask,
|
||||||
|
_locked_mods: ModMask,
|
||||||
|
_keyboard: KeyboardHandle<Self>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delegate_virtual_keyboard_manager!(State);
|
||||||
Reference in New Issue
Block a user