Integrate native Rime and stabilize input, output, and rendering

- Add optional modifier-only Super binding whose tap is cancelled by
  other input, focus changes, grabs, locks, and session teardown.
- Ship the native ferese-rime user service, Rime defaults, installer
  inventory, package dependencies, session environment, and docs.
- Vendor Smithay 8a27023 with the SHM texture-cache format fix and add
  GPU regressions for format changes and resize snapshots.
- Release reused CRTC owners before staging output modes, then restore
  changed outputs before former owners when a transaction fails.
- Wait for resize-capture GPU completion, expand filtered surface
  damage, and preserve IME popup origin under fractional scaling.
- Mark weekends like holidays in both calendar layouts.
This commit is contained in:
aria committed 2026-10-30 03:13:43 +09:00
1 parent a2be421974
commit 993bc0f88f
391 files changed
+130908 -76

No files matched your search

+32
View File
@@ -1,6 +1,7 @@
mod window;
pub(crate) use window::WindowInteraction;
mod pointer;
pub(crate) mod super_tap;
use ferese_layout::Direction;
pub(crate) use pointer::ScrollBindings;
use smithay::backend::input::{
@@ -150,6 +151,16 @@ impl Ferese {
event: InputEvent<I>,
source: KeyboardSource,
) {
match &event {
InputEvent::Keyboard { event } => self.super_tap.observe_key(source, event.key_code()),
InputEvent::PointerButton { event } => self.super_tap.pointer_button(
event.device().id(),
event.button_code(),
event.state(),
),
InputEvent::DeviceRemoved { device } => self.super_tap.device_removed(&device.id()),
_ => self.super_tap.cancel(),
}
if self.input_capture.active() {
self.set_binding_mode("default");
}
@@ -320,6 +331,10 @@ impl Ferese {
let keyboard = self.seat.get_keyboard().expect("seat has a keyboard");
let keycode = event.key_code();
let state = event.state();
let keys_were_clear = keyboard.pressed_keys().is_empty();
let tap_focus = keyboard.current_focus().map(|surface| surface.id());
let tap_allowed = self.super_tap_allowed(&keyboard);
let mut tap_action = None;
let was_captured = self.input_capture.active();
if self.input_capture.captures(1) {
@@ -349,6 +364,18 @@ impl Ferese {
serial,
event.time(),
|data, modifiers, keysym| {
if state == KeyState::Released {
if data.super_tap.release(source, keycode, tap_allowed, tap_focus.clone()) {
tap_action = data.binding_modes.bindings(&data.bindings)
.super_tap().map(|binding| binding.action.clone());
}
} else if keys_were_clear && tap_allowed
&& !modifiers.ctrl && !modifiers.alt && !modifiers.shift
&& keysym.raw_syms().iter().any(|symbol| matches!(symbol.raw(), keysyms::KEY_Super_L | keysyms::KEY_Super_R))
&& data.binding_modes.bindings(&data.bindings).super_tap().is_some()
{
data.super_tap.arm(source, keycode, tap_focus.clone());
}
if data.focus_cycle.is_some() {
if data.session_lock.active() || data.input_capture.captures(1) {
data.cancel_focus_cycle();
@@ -530,6 +557,11 @@ impl Ferese {
FilterResult::Intercept(())
},
);
// Finish forwarding the original release to its owner before
// changing focus or opening a layer surface for the action.
if let Some(action) = tap_action {
self.execute_binding(action);
}
if state == KeyState::Pressed && intercepted.is_none() && client_grab {
self.record_activation_input(serial, interaction_focus);
}