feat: support authorized input methods
This commit is contained in:
1 parent
6dc2a5300e
commit
f6dce3316a
4 files changed
+87
-1
No files matched your search
@@ -3,7 +3,7 @@
|
|||||||
Ferese is an experimental Wayland tiling compositor written in Rust with
|
Ferese is an experimental Wayland tiling compositor written in Rust with
|
||||||
Smithay. The nested M0–M3 path is complete, including tiling, workspaces, and
|
Smithay. The nested M0–M3 path is complete, including tiling, workspaces, and
|
||||||
timestamp-driven animated geometry. Development now targets the M4 early
|
timestamp-driven animated geometry. Development now targets the M4 early
|
||||||
hardware-session milestone in the
|
hardware-session acceptance pass and M5 native interoperability in the
|
||||||
[window-manager specification](docs/ferese-window-manager-spec.md).
|
[window-manager specification](docs/ferese-window-manager-spec.md).
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
@@ -23,6 +23,17 @@ cargo run -p ferese -- foot
|
|||||||
|
|
||||||
Set `RUST_LOG=ferese=debug` for detailed compositor logging.
|
Set `RUST_LOG=ferese=debug` for detailed compositor logging.
|
||||||
|
|
||||||
|
Text-input-v3 is available to applications by default. Input-method-v2 is
|
||||||
|
hidden unless the session explicitly opts in, because an input method can
|
||||||
|
request privileged keyboard access. Enable it only when launching a trusted
|
||||||
|
IME for the session:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
FERESE_ENABLE_INPUT_METHOD=1 cargo run -p ferese
|
||||||
|
```
|
||||||
|
|
||||||
|
`Ctrl+Alt+Escape` always releases an active client shortcut inhibitor.
|
||||||
|
|
||||||
### Direct DRM session
|
### Direct DRM session
|
||||||
|
|
||||||
Run the hardware backend from a spare TTY, outside another graphical session:
|
Run the hardware backend from a spare TTY, outside another graphical session:
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
use smithay::{
|
||||||
|
desktop::{PopupKind, WindowSurfaceType, layer_map_for_output},
|
||||||
|
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||||
|
utils::{Logical, Rectangle},
|
||||||
|
wayland::input_method::{InputMethodHandler, PopupSurface},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::Ferese;
|
||||||
|
|
||||||
|
impl InputMethodHandler for Ferese {
|
||||||
|
fn new_popup(&mut self, surface: PopupSurface) {
|
||||||
|
if let Err(error) = self
|
||||||
|
.popups
|
||||||
|
.track_popup(PopupKind::InputMethod(surface.clone()))
|
||||||
|
{
|
||||||
|
tracing::warn!(?error, "failed to track input method popup");
|
||||||
|
}
|
||||||
|
crate::backends::direct::render_all(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dismiss_popup(&mut self, _surface: PopupSurface) {
|
||||||
|
self.popups.cleanup();
|
||||||
|
crate::backends::direct::render_all(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn popup_repositioned(&mut self, _surface: PopupSurface) {
|
||||||
|
crate::backends::direct::render_all(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parent_geometry(&self, parent: &WlSurface) -> Rectangle<i32, Logical> {
|
||||||
|
if let Some(geometry) = self.space.elements().find_map(|window| {
|
||||||
|
window
|
||||||
|
.toplevel()
|
||||||
|
.is_some_and(|toplevel| toplevel.wl_surface() == parent)
|
||||||
|
.then(|| self.space.element_geometry(window))
|
||||||
|
.flatten()
|
||||||
|
}) {
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(layer) = self
|
||||||
|
.space
|
||||||
|
.layer_for_surface(parent, WindowSurfaceType::TOPLEVEL)
|
||||||
|
else {
|
||||||
|
return Rectangle::default();
|
||||||
|
};
|
||||||
|
|
||||||
|
self.space
|
||||||
|
.outputs()
|
||||||
|
.find_map(|output| {
|
||||||
|
let output_geometry = self.space.output_geometry(output)?;
|
||||||
|
let layer_geometry = layer_map_for_output(output).layer_geometry(&layer)?;
|
||||||
|
|
||||||
|
Some(Rectangle::new(
|
||||||
|
output_geometry.loc + layer_geometry.loc,
|
||||||
|
layer_geometry.size,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
mod activation;
|
mod activation;
|
||||||
mod compositor;
|
mod compositor;
|
||||||
|
mod input_method;
|
||||||
mod layer_shell;
|
mod layer_shell;
|
||||||
mod xdg_shell;
|
mod xdg_shell;
|
||||||
|
|
||||||
@@ -237,6 +238,7 @@ smithay::delegate_data_device!(Ferese);
|
|||||||
smithay::delegate_fractional_scale!(Ferese);
|
smithay::delegate_fractional_scale!(Ferese);
|
||||||
smithay::delegate_idle_inhibit!(Ferese);
|
smithay::delegate_idle_inhibit!(Ferese);
|
||||||
smithay::delegate_idle_notify!(Ferese);
|
smithay::delegate_idle_notify!(Ferese);
|
||||||
|
smithay::delegate_input_method_manager!(Ferese);
|
||||||
smithay::delegate_keyboard_shortcuts_inhibit!(Ferese);
|
smithay::delegate_keyboard_shortcuts_inhibit!(Ferese);
|
||||||
smithay::delegate_layer_shell!(Ferese);
|
smithay::delegate_layer_shell!(Ferese);
|
||||||
smithay::delegate_output!(Ferese);
|
smithay::delegate_output!(Ferese);
|
||||||
@@ -247,6 +249,7 @@ smithay::delegate_relative_pointer!(Ferese);
|
|||||||
smithay::delegate_seat!(Ferese);
|
smithay::delegate_seat!(Ferese);
|
||||||
smithay::delegate_shm!(Ferese);
|
smithay::delegate_shm!(Ferese);
|
||||||
smithay::delegate_single_pixel_buffer!(Ferese);
|
smithay::delegate_single_pixel_buffer!(Ferese);
|
||||||
|
smithay::delegate_text_input_manager!(Ferese);
|
||||||
smithay::delegate_viewporter!(Ferese);
|
smithay::delegate_viewporter!(Ferese);
|
||||||
smithay::delegate_xdg_activation!(Ferese);
|
smithay::delegate_xdg_activation!(Ferese);
|
||||||
smithay::delegate_xdg_decoration!(Ferese);
|
smithay::delegate_xdg_decoration!(Ferese);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ use smithay::{
|
|||||||
fractional_scale::FractionalScaleManagerState,
|
fractional_scale::FractionalScaleManagerState,
|
||||||
idle_inhibit::IdleInhibitManagerState,
|
idle_inhibit::IdleInhibitManagerState,
|
||||||
idle_notify::IdleNotifierState,
|
idle_notify::IdleNotifierState,
|
||||||
|
input_method::InputMethodManagerState,
|
||||||
keyboard_shortcuts_inhibit::{KeyboardShortcutsInhibitState, KeyboardShortcutsInhibitor},
|
keyboard_shortcuts_inhibit::{KeyboardShortcutsInhibitState, KeyboardShortcutsInhibitor},
|
||||||
output::OutputManagerState,
|
output::OutputManagerState,
|
||||||
pointer_constraints::PointerConstraintsState,
|
pointer_constraints::PointerConstraintsState,
|
||||||
@@ -50,6 +51,7 @@ use smithay::{
|
|||||||
shm::ShmState,
|
shm::ShmState,
|
||||||
single_pixel_buffer::SinglePixelBufferState,
|
single_pixel_buffer::SinglePixelBufferState,
|
||||||
socket::ListeningSocketSource,
|
socket::ListeningSocketSource,
|
||||||
|
text_input::TextInputManagerState,
|
||||||
viewporter::ViewporterState,
|
viewporter::ViewporterState,
|
||||||
xdg_activation::XdgActivationState,
|
xdg_activation::XdgActivationState,
|
||||||
xdg_foreign::XdgForeignState,
|
xdg_foreign::XdgForeignState,
|
||||||
@@ -84,6 +86,7 @@ pub struct Ferese {
|
|||||||
pub fractional_scale_state: FractionalScaleManagerState,
|
pub fractional_scale_state: FractionalScaleManagerState,
|
||||||
pub idle_inhibit_state: IdleInhibitManagerState,
|
pub idle_inhibit_state: IdleInhibitManagerState,
|
||||||
pub idle_notifier_state: IdleNotifierState<Self>,
|
pub idle_notifier_state: IdleNotifierState<Self>,
|
||||||
|
pub input_method_manager_state: InputMethodManagerState,
|
||||||
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
|
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
|
||||||
pub output_manager_state: OutputManagerState,
|
pub output_manager_state: OutputManagerState,
|
||||||
pub pointer_constraints_state: PointerConstraintsState,
|
pub pointer_constraints_state: PointerConstraintsState,
|
||||||
@@ -93,6 +96,7 @@ pub struct Ferese {
|
|||||||
pub seat_state: SeatState<Self>,
|
pub seat_state: SeatState<Self>,
|
||||||
pub shm_state: ShmState,
|
pub shm_state: ShmState,
|
||||||
pub single_pixel_buffer_state: SinglePixelBufferState,
|
pub single_pixel_buffer_state: SinglePixelBufferState,
|
||||||
|
pub text_input_manager_state: TextInputManagerState,
|
||||||
pub viewporter_state: ViewporterState,
|
pub viewporter_state: ViewporterState,
|
||||||
pub layer_shell_state: WlrLayerShellState,
|
pub layer_shell_state: WlrLayerShellState,
|
||||||
pub xdg_activation_state: XdgActivationState,
|
pub xdg_activation_state: XdgActivationState,
|
||||||
@@ -113,10 +117,15 @@ impl Ferese {
|
|||||||
let fractional_scale_state = FractionalScaleManagerState::new::<Self>(&display_handle);
|
let fractional_scale_state = FractionalScaleManagerState::new::<Self>(&display_handle);
|
||||||
let idle_inhibit_state = IdleInhibitManagerState::new::<Self>(&display_handle);
|
let idle_inhibit_state = IdleInhibitManagerState::new::<Self>(&display_handle);
|
||||||
let idle_notifier_state = IdleNotifierState::new(&display_handle, event_loop.handle());
|
let idle_notifier_state = IdleNotifierState::new(&display_handle, event_loop.handle());
|
||||||
|
let input_method_enabled =
|
||||||
|
std::env::var_os("FERESE_ENABLE_INPUT_METHOD").is_some_and(|value| value == "1");
|
||||||
|
let input_method_manager_state =
|
||||||
|
InputMethodManagerState::new::<Self, _>(&display_handle, move |_| input_method_enabled);
|
||||||
let keyboard_shortcuts_inhibit_state =
|
let keyboard_shortcuts_inhibit_state =
|
||||||
KeyboardShortcutsInhibitState::new::<Self>(&display_handle);
|
KeyboardShortcutsInhibitState::new::<Self>(&display_handle);
|
||||||
let shm_state = ShmState::new::<Self>(&display_handle, Vec::new());
|
let shm_state = ShmState::new::<Self>(&display_handle, Vec::new());
|
||||||
let single_pixel_buffer_state = SinglePixelBufferState::new::<Self>(&display_handle);
|
let single_pixel_buffer_state = SinglePixelBufferState::new::<Self>(&display_handle);
|
||||||
|
let text_input_manager_state = TextInputManagerState::new::<Self>(&display_handle);
|
||||||
let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&display_handle);
|
let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&display_handle);
|
||||||
let pointer_constraints_state = PointerConstraintsState::new::<Self>(&display_handle);
|
let pointer_constraints_state = PointerConstraintsState::new::<Self>(&display_handle);
|
||||||
let presentation_state =
|
let presentation_state =
|
||||||
@@ -167,6 +176,7 @@ impl Ferese {
|
|||||||
fractional_scale_state,
|
fractional_scale_state,
|
||||||
idle_inhibit_state,
|
idle_inhibit_state,
|
||||||
idle_notifier_state,
|
idle_notifier_state,
|
||||||
|
input_method_manager_state,
|
||||||
keyboard_shortcuts_inhibit_state,
|
keyboard_shortcuts_inhibit_state,
|
||||||
output_manager_state,
|
output_manager_state,
|
||||||
pointer_constraints_state,
|
pointer_constraints_state,
|
||||||
@@ -176,6 +186,7 @@ impl Ferese {
|
|||||||
seat_state,
|
seat_state,
|
||||||
shm_state,
|
shm_state,
|
||||||
single_pixel_buffer_state,
|
single_pixel_buffer_state,
|
||||||
|
text_input_manager_state,
|
||||||
viewporter_state,
|
viewporter_state,
|
||||||
layer_shell_state,
|
layer_shell_state,
|
||||||
xdg_activation_state,
|
xdg_activation_state,
|
||||||
|
|||||||
Reference in new issue
Block a user