Linux/x11 input handling (#7811)
Implements the basics of keyboard and mouse handling. Some keys will need special treatment, like Backspace/Delete. In this PR, all keys are treated as append-only. Leaving this for a follow-up. I used @gabydd 's branch as a reference (thank you!) as well as https://github.com/xkbcommon/libxkbcommon/blob/master/doc/quick-guide.md For future work, I'll also use https://github.com/xkbcommon/libxkbcommon/blob/master/tools/interactive-x11.c All commits are separately compileable and reviewable. Release Notes: - N/A --------- Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
aa319ccfd0
commit
a41fb29e01
15 changed files with 253 additions and 53 deletions
|
@ -13,15 +13,12 @@ use std::{
|
|||
use blade_graphics as gpu;
|
||||
use parking_lot::Mutex;
|
||||
use raw_window_handle as rwh;
|
||||
use xcb::{
|
||||
x::{self, StackMode},
|
||||
Xid as _,
|
||||
};
|
||||
use xcb::{x, Xid as _};
|
||||
|
||||
use crate::platform::linux::blade_renderer::BladeRenderer;
|
||||
use crate::{
|
||||
Bounds, GlobalPixels, Pixels, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
|
||||
Size, WindowAppearance, WindowBounds, WindowOptions, X11Display,
|
||||
Bounds, GlobalPixels, Pixels, PlatformDisplay, PlatformInput, PlatformInputHandler,
|
||||
PlatformWindow, Point, Size, WindowAppearance, WindowBounds, WindowOptions, X11Display,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -52,6 +49,7 @@ struct LinuxWindowInner {
|
|||
bounds: Bounds<i32>,
|
||||
scale_factor: f32,
|
||||
renderer: BladeRenderer,
|
||||
input_handler: Option<PlatformInputHandler>,
|
||||
}
|
||||
|
||||
impl LinuxWindowInner {
|
||||
|
@ -152,7 +150,19 @@ impl X11WindowState {
|
|||
let xcb_values = [
|
||||
x::Cw::BackPixel(screen.white_pixel()),
|
||||
x::Cw::EventMask(
|
||||
x::EventMask::EXPOSURE | x::EventMask::STRUCTURE_NOTIFY | x::EventMask::KEY_PRESS,
|
||||
x::EventMask::EXPOSURE
|
||||
| x::EventMask::STRUCTURE_NOTIFY
|
||||
| x::EventMask::KEY_PRESS
|
||||
| x::EventMask::KEY_RELEASE
|
||||
| x::EventMask::BUTTON_PRESS
|
||||
| x::EventMask::BUTTON_RELEASE
|
||||
| x::EventMask::POINTER_MOTION
|
||||
| x::EventMask::BUTTON1_MOTION
|
||||
| x::EventMask::BUTTON2_MOTION
|
||||
| x::EventMask::BUTTON3_MOTION
|
||||
| x::EventMask::BUTTON4_MOTION
|
||||
| x::EventMask::BUTTON5_MOTION
|
||||
| x::EventMask::BUTTON_MOTION,
|
||||
),
|
||||
];
|
||||
|
||||
|
@ -238,7 +248,7 @@ impl X11WindowState {
|
|||
|
||||
// Note: this has to be done after the GPU init, or otherwise
|
||||
// the sizes are immediately invalidated.
|
||||
let gpu_extent = query_render_extent(&xcb_connection, x_window);
|
||||
let gpu_extent = query_render_extent(xcb_connection, x_window);
|
||||
|
||||
Self {
|
||||
xcb_connection: Arc::clone(xcb_connection),
|
||||
|
@ -250,6 +260,7 @@ impl X11WindowState {
|
|||
bounds,
|
||||
scale_factor: 1.0,
|
||||
renderer: BladeRenderer::new(gpu, gpu_extent),
|
||||
input_handler: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -313,6 +324,20 @@ impl X11WindowState {
|
|||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn handle_input(&self, input: PlatformInput) {
|
||||
if let Some(ref mut fun) = self.callbacks.lock().input {
|
||||
if fun(input.clone()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let PlatformInput::KeyDown(event) = input {
|
||||
let mut inner = self.inner.lock();
|
||||
if let Some(ref mut input_handler) = inner.input_handler {
|
||||
input_handler.replace_text_in_range(None, &event.keystroke.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformWindow for X11Window {
|
||||
|
@ -356,12 +381,12 @@ impl PlatformWindow for X11Window {
|
|||
self
|
||||
}
|
||||
|
||||
//todo!(linux)
|
||||
fn set_input_handler(&mut self, input_handler: PlatformInputHandler) {}
|
||||
fn set_input_handler(&mut self, input_handler: PlatformInputHandler) {
|
||||
self.0.inner.lock().input_handler = Some(input_handler);
|
||||
}
|
||||
|
||||
//todo!(linux)
|
||||
fn take_input_handler(&mut self) -> Option<PlatformInputHandler> {
|
||||
None
|
||||
self.0.inner.lock().input_handler.take()
|
||||
}
|
||||
|
||||
//todo!(linux)
|
||||
|
@ -378,7 +403,7 @@ impl PlatformWindow for X11Window {
|
|||
fn activate(&self) {
|
||||
self.0.xcb_connection.send_request(&x::ConfigureWindow {
|
||||
window: self.0.x_window,
|
||||
value_list: &[x::ConfigWindow::StackMode(StackMode::Above)],
|
||||
value_list: &[x::ConfigWindow::StackMode(x::StackMode::Above)],
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue