Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: impl xkb common #9

Merged
merged 16 commits into from
Jul 31, 2024
Merged
1 change: 1 addition & 0 deletions .github/workflows/rustci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
run: sudo apt install -y libxkbcommon-dev libpango1.0-dev libwayland-dev
- name: Publish to crate
run: |
cargo publish -p waycrate_xkbkeycode --token ${{ secrets.CRATES_TOKEN }}
cargo publish -p layershellev --token ${{ secrets.CRATES_TOKEN }}
cargo publish -p sessionlockev --token ${{ secrets.CRATES_TOKEN }}
cargo publish -p iced_layershell --token ${{ secrets.CRATES_TOKEN }}
Expand Down
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"iced_sessionlock",
"starcolorkeyboard",
"sessionlockev",
"waycrate_xkbkeycode",
"iced_examples/*",
]

Expand All @@ -27,7 +28,8 @@ layershellev = { version = "0.2.7", path = "./layershellev" }
sessionlockev = { version = "0.2.7", path = "./sessionlockev" }

iced_layershell = { version = "0.2.7", path = "./iced_layershell" }
iced_sessionlock = { version = "0.2.7", path = "./iced_sessionlock"}
iced_sessionlock = { version = "0.2.7", path = "./iced_sessionlock" }
waycrate_xkbkeycode = { version = "0.2.7", path = "./waycrate_xkbkeycode" }

tempfile = "3.8.1"
thiserror = "1.0.50"
Expand Down Expand Up @@ -68,3 +70,7 @@ iced_futures = "0.12.0"
iced_graphics = "0.12.0"
bitflags = "2.6.0"
log = "0.4.22"

xkbcommon-dl = "0.4.2"
smol_str = "0.2.2"
memmap2 = "0.9.4"
3 changes: 3 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[files]
extend-exclude = ["**/Cargo.lock"]

[default.extend-words]
Calculater = "Calculater"
3 changes: 3 additions & 0 deletions iced_layershell/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ tracing = "0.1.40"
thiserror = "1.0.56"
layershellev.workspace = true
futures = "0.3.30"

memmap2 = "0.9.4"
xkbcommon-dl = "0.4.2"
56 changes: 11 additions & 45 deletions iced_layershell/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ use iced_style::application::StyleSheet;

use iced_futures::{Executor, Runtime, Subscription};

use layershellev::{
reexport::wayland_client::{KeyState, WEnum},
LayerEvent, ReturnData, WindowState, WindowWrapper,
};
use layershellev::{LayerEvent, ReturnData, WindowState, WindowWrapper};

use futures::{channel::mpsc, SinkExt, StreamExt};

Expand Down Expand Up @@ -189,8 +186,6 @@ where
let mut context = task::Context::from_waker(task::noop_waker_ref());

let mut pointer_serial: u32 = 0;
let mut key_event: Option<IcedLayerEvent<A::Message>> = None;
let mut key_ping_count: u32 = 400;

let _ = ev.running_with_proxy(message_receiver, move |event, ev, _| {
use layershellev::DispatchMessage;
Expand All @@ -199,50 +194,19 @@ where
// TODO: maybe use it later
LayerEvent::BindProvide(_, _) => {}
LayerEvent::RequestMessages(message) => {
match message {
DispatchMessage::MouseEnter { serial, .. } => {
pointer_serial = *serial;
}
DispatchMessage::KeyBoard { state, .. } => {
if let WEnum::Value(KeyState::Pressed) = state {
key_event = Some(message.into());
} else {
key_event = None;
key_ping_count = 400;
}
}
_ => {}
if let DispatchMessage::MouseEnter { serial, .. } = message {
pointer_serial = *serial;
}

event_sender
.start_send(message.into())
.expect("Cannot send");
}
LayerEvent::NormalDispatch => match &key_event {
Some(keyevent) => {
if let IcedLayerEvent::Window(windowevent) = keyevent {
let event = IcedLayerEvent::Window(*windowevent);
if key_ping_count > 70 && key_ping_count < 74 {
event_sender.start_send(event).expect("Cannot send");
key_ping_count = 0;
} else {
event_sender
.start_send(IcedLayerEvent::NormalUpdate)
.expect("Cannot send");
}
if key_ping_count >= 74 {
key_ping_count -= 1;
} else {
key_ping_count += 1;
}
}
}
None => {
event_sender
.start_send(IcedLayerEvent::NormalUpdate)
.expect("Cannot send");
}
},
LayerEvent::NormalDispatch => {
event_sender
.start_send(IcedLayerEvent::NormalUpdate)
.expect("Cannot send");
}
LayerEvent::UserEvent(event) => {
event_sender
.start_send(IcedLayerEvent::UserEvent(event))
Expand Down Expand Up @@ -439,7 +403,9 @@ async fn run_instance<A, E, C>(
IcedLayerEvent::Window(event) => {
state.update(&event);

if let Some(event) = conversion::window_event(IcedCoreWindow::Id::MAIN, &event) {
if let Some(event) =
conversion::window_event(IcedCoreWindow::Id::MAIN, &event, state.modifiers())
{
events.push(event);
}
}
Expand Down
10 changes: 10 additions & 0 deletions iced_layershell/src/application/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::application::Application;
use iced_core::{mouse as IcedMouse, Color, Point, Size};
use iced_graphics::Viewport;
use iced_style::application::{self, StyleSheet};
use layershellev::keyboard::ModifiersState;

use crate::event::WindowEvent;

Expand All @@ -15,6 +16,7 @@ where
theme: A::Theme,
appearance: application::Appearance,
mouse_position: Option<Point>,
modifiers: ModifiersState,
}

impl<A: Application> State<A>
Expand All @@ -38,9 +40,14 @@ where
theme,
appearance,
mouse_position: None,
modifiers: ModifiersState::default(),
}
}

pub fn modifiers(&self) -> ModifiersState {
self.modifiers
}

pub fn update_view_port(&mut self, width: u32, height: u32) {
self.viewport = Viewport::with_physical_size(
iced_core::Size::new(width, height),
Expand Down Expand Up @@ -90,6 +97,9 @@ where
WindowEvent::CursorMoved { x, y } => {
self.mouse_position = Some(Point::new(*x as f32, *y as f32));
}
WindowEvent::ModifiersChanged(modifiers) => {
self.modifiers = *modifiers;
}
_ => {}
}
}
Expand Down
62 changes: 41 additions & 21 deletions iced_layershell/src/conversion.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
mod keymap;

use crate::event::IcedButtonState;
use crate::event::IcedKeyState;
use crate::event::WindowEvent as LayerShellEvent;
use keymap::{key_from_u32, text_from_key};

use iced_core::SmolStr;
use iced_core::{keyboard, mouse, Event as IcedEvent};
use keymap::key;
use layershellev::keyboard::KeyLocation;
use layershellev::keyboard::ModifiersState;
use layershellev::xkb_keyboard::ElementState;
use layershellev::xkb_keyboard::KeyEvent as LayerShellKeyEvent;

#[allow(unused)]
pub fn window_event(id: iced_core::window::Id, layerevent: &LayerShellEvent) -> Option<IcedEvent> {
pub fn window_event(
id: iced_core::window::Id,
layerevent: &LayerShellEvent,
modifiers: ModifiersState,
) -> Option<IcedEvent> {
match layerevent {
LayerShellEvent::CursorLeft => Some(IcedEvent::Mouse(mouse::Event::CursorLeft)),
LayerShellEvent::CursorMoved { x, y } => {
Expand All @@ -33,27 +40,41 @@ pub fn window_event(id: iced_core::window::Id, layerevent: &LayerShellEvent) ->
delta: mouse::ScrollDelta::Pixels { x: *x, y: *y },
}))
}
LayerShellEvent::Keyboard {
state,
key,
modifiers,
} => {
let key = key_from_u32(*key);
let text = text_from_key(&key);
LayerShellEvent::KeyBoardInput { event, .. } => Some(IcedEvent::Keyboard({
let logical_key = event.key_without_modifiers();
let text = event
.text_with_all_modifiers()
.map(SmolStr::new)
.filter(|text| !text.as_str().chars().any(is_private_use));
let LayerShellKeyEvent {
state, location, ..
} = event;
let key = key(logical_key);
let modifiers = keymap::modifiers(modifiers);

let location = match location {
KeyLocation::Standard => keyboard::Location::Standard,
KeyLocation::Left => keyboard::Location::Left,
KeyLocation::Right => keyboard::Location::Right,
KeyLocation::Numpad => keyboard::Location::Numpad,
};
match state {
IcedKeyState::Pressed => Some(IcedEvent::Keyboard(keyboard::Event::KeyPressed {
ElementState::Pressed => keyboard::Event::KeyPressed {
key,
location: keyboard::Location::Standard,
modifiers: *modifiers,
location,
modifiers,
text,
})),
IcedKeyState::Released => Some(IcedEvent::Keyboard(keyboard::Event::KeyReleased {
},
ElementState::Released => keyboard::Event::KeyReleased {
key,
location: keyboard::Location::Standard,
modifiers: *modifiers,
})),
location,
modifiers,
},
}
}
})),
LayerShellEvent::ModifiersChanged(new_modifiers) => Some(IcedEvent::Keyboard(
keyboard::Event::ModifiersChanged(keymap::modifiers(*new_modifiers)),
)),
_ => None,
}
}
Expand All @@ -75,7 +96,6 @@ pub(crate) fn mouse_interaction(interaction: mouse::Interaction) -> String {
}
}

#[allow(unused)]
fn is_private_use(c: char) -> bool {
('\u{E000}'..='\u{F8FF}').contains(&c)
}
Loading