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

Added basic support for input_regions #111

Merged
merged 7 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions iced_layershell/README.md
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should i just create an examples folder and add this example there instead?, since i feel like readme should have a minimal example only

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean add an examples folder and add this example instead. And it will be better to add comments in the place of this code

Original file line number Diff line number Diff line change
Expand Up @@ -468,4 +468,83 @@ impl Counter {

```

### Dynamically set input region
```rust, no_run

use iced::widget::{button, row, Space};
use iced::{Color, Element, Length, Task as Command, Theme};
use iced_layershell::settings::{LayerShellSettings, Settings};
use iced_layershell::to_layer_message;
use iced_layershell::Application;

pub fn main() -> Result<(), iced_layershell::Error> {
InputRegionExample::run(Settings {
layer_settings: LayerShellSettings {
size: Some((400, 400)),
..Default::default()
},
..Default::default()
})
}

struct InputRegionExample;

#[to_layer_message]
#[derive(Debug, Clone)]
#[doc = "Some docs"]
enum Message {
SetRegion,
UnsetRegion,
}

impl Application for InputRegionExample {
type Message = Message;
type Flags = ();
type Theme = Theme;
type Executor = iced::executor::Default;

fn new(_flags: ()) -> (Self, Command<Message>) {
(Self, Command::none())
}

fn namespace(&self) -> String {
String::from("Counter - Iced")
}

fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::SetRegion => Command::done(Message::SetInputRegion(|region| {
// Only the buttons!
region.add(0, 0, 400, 70);
})),
Message::UnsetRegion => Command::done(Message::SetInputRegion(|region| {
// Entire window!
region.add(0, 0, 400, 400);
})),
_ => unreachable!(),
}
}

fn view(&self) -> Element<Message> {
// Create the top row with two buttons
row![
button("Set region").on_press(Message::SetRegion),
Space::with_width(Length::Fill),
button("Reset region").on_press(Message::UnsetRegion),
]
.padding(20)
.spacing(10)
.width(Length::Fill)
.into()
}

fn style(&self, theme: &Self::Theme) -> iced_layershell::Appearance {
use iced_layershell::Appearance;
Appearance {
background_color: Color::from_rgba(0.3, 0.3, 0.3, 0.3),
text_color: theme.palette().text,
}
}
}
```
For more example, please take a look at [exwlshelleventloop](https://github.com/waycrate/exwlshelleventloop)
3 changes: 2 additions & 1 deletion iced_layershell/src/actions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::reexport::{Anchor, Layer};
use crate::reexport::{Anchor, Layer, WlRegion};
use iced::window::Id as IcedId;
use iced_core::mouse::Interaction;
use layershellev::id::Id as LayerId;
Expand Down Expand Up @@ -69,6 +69,7 @@ pub enum LayershellCustomActions {
settings: NewLayerShellSettings,
id: IcedId,
},
SetInputRegion(fn(&WlRegion)),
NewPopUp {
settings: IcedNewPopupSettings,
id: IcedId,
Expand Down
61 changes: 40 additions & 21 deletions iced_layershell/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use iced_futures::{Executor, Runtime, Subscription};

use layershellev::{
calloop::timer::{TimeoutAction, Timer},
reexport::wayland_client::{WlCompositor, WlRegion},
reexport::zwp_virtual_keyboard_v1,
LayerEvent, ReturnData, StartMode, WindowWrapper,
};
Expand Down Expand Up @@ -196,36 +197,41 @@ where
));

let mut context = task::Context::from_waker(task::noop_waker_ref());

let mut wl_input_region: Option<WlRegion> = None;
let mut pointer_serial: u32 = 0;

let _ = ev.running_with_proxy(message_receiver, move |event, ev, _| {
use layershellev::DispatchMessage;
let mut def_returndata = ReturnData::None;
match event {
LayerEvent::InitRequest => {
if settings.virtual_keyboard_support.is_some() {
def_returndata = ReturnData::RequestBind;
}
def_returndata = ReturnData::RequestBind;
}
LayerEvent::BindProvide(globals, qh) => {
let virtual_keyboard_manager = globals
.bind::<zwp_virtual_keyboard_v1::ZwpVirtualKeyboardManagerV1, _, _>(
qh,
1..=1,
(),
)
.expect("no support virtual_keyboard");
let VirtualKeyboardSettings {
file,
keymap_size,
keymap_format,
} = settings.virtual_keyboard_support.as_ref().unwrap();
let seat = ev.get_seat();
let virtual_keyboard_in =
virtual_keyboard_manager.create_virtual_keyboard(seat, qh, ());
virtual_keyboard_in.keymap((*keymap_format).into(), file.as_fd(), *keymap_size);
ev.set_virtual_keyboard(virtual_keyboard_in);
let wl_compositor = globals
.bind::<WlCompositor, _, _>(qh, 1..=1, ())
.expect("could not bind wl_compositor");
wl_input_region = Some(wl_compositor.create_region(qh, ()));

if settings.virtual_keyboard_support.is_some() {
let virtual_keyboard_manager = globals
.bind::<zwp_virtual_keyboard_v1::ZwpVirtualKeyboardManagerV1, _, _>(
qh,
1..=1,
(),
)
.expect("no support virtual_keyboard");
let VirtualKeyboardSettings {
file,
keymap_size,
keymap_format,
} = settings.virtual_keyboard_support.as_ref().unwrap();
let seat = ev.get_seat();
let virtual_keyboard_in =
virtual_keyboard_manager.create_virtual_keyboard(seat, qh, ());
virtual_keyboard_in.keymap((*keymap_format).into(), file.as_fd(), *keymap_size);
ev.set_virtual_keyboard(virtual_keyboard_in);
}
}
LayerEvent::RequestMessages(message) => {
if let DispatchMessage::MouseEnter { serial, .. } = message {
Expand Down Expand Up @@ -269,6 +275,19 @@ where
LayershellCustomActions::LayerChange(layer) => {
ev.main_window().set_layer(layer);
}
LayershellCustomActions::SetInputRegion(set_region) => {
let window = ev.main_window();

let region = wl_input_region.as_ref().expect("region not found");
let window_size = window.get_size();
let width: i32 = window_size.0.try_into().unwrap_or_default();
let height: i32 = window_size.1.try_into().unwrap_or_default();

region.subtract(0, 0, width, height);
set_region(&region);

window.get_wlsurface().set_input_region(Some(&region));
}
LayershellCustomActions::MarginChange(margin) => {
ev.main_window().set_margin(margin);
}
Expand Down
2 changes: 1 addition & 1 deletion iced_layershell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod sandbox;
pub mod settings;

pub mod reexport {
pub use layershellev::reexport::wayland_client::wl_keyboard;
pub use layershellev::reexport::wayland_client::{wl_keyboard, WlRegion};
pub use layershellev::reexport::Anchor;
pub use layershellev::reexport::KeyboardInteractivity;
pub use layershellev::reexport::Layer;
Expand Down
69 changes: 49 additions & 20 deletions iced_layershell/src/multi_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use iced_futures::{Executor, Runtime, Subscription};

use layershellev::{
calloop::timer::{TimeoutAction, Timer},
reexport::wayland_client::{WlCompositor, WlRegion},
reexport::zwp_virtual_keyboard_v1,
LayerEvent, NewPopUpSettings, ReturnData, WindowState, WindowWrapper,
};
Expand Down Expand Up @@ -210,6 +211,7 @@ where
let mut context = task::Context::from_waker(task::noop_waker_ref());

let mut pointer_serial: u32 = 0;
let mut wl_input_region: Option<WlRegion> = None;

let _ = ev.running_with_proxy(message_receiver, move |event, ev, index| {
use layershellev::DispatchMessage;
Expand All @@ -219,28 +221,33 @@ where
.map(|unit| unit.id());
match event {
LayerEvent::InitRequest => {
if settings.virtual_keyboard_support.is_some() {
def_returndata = ReturnData::RequestBind;
}
def_returndata = ReturnData::RequestBind;
}
LayerEvent::BindProvide(globals, qh) => {
let virtual_keyboard_manager = globals
.bind::<zwp_virtual_keyboard_v1::ZwpVirtualKeyboardManagerV1, _, _>(
qh,
1..=1,
(),
)
.expect("no support virtual_keyboard");
let VirtualKeyboardSettings {
file,
keymap_size,
keymap_format,
} = settings.virtual_keyboard_support.as_ref().unwrap();
let seat = ev.get_seat();
let virtual_keyboard_in =
virtual_keyboard_manager.create_virtual_keyboard(seat, qh, ());
virtual_keyboard_in.keymap((*keymap_format).into(), file.as_fd(), *keymap_size);
ev.set_virtual_keyboard(virtual_keyboard_in);
let wl_compositor = globals
.bind::<WlCompositor, _, _>(qh, 1..=1, ())
.expect("could not bind wl_compositor");
wl_input_region = Some(wl_compositor.create_region(qh, ()));

if settings.virtual_keyboard_support.is_some() {
let virtual_keyboard_manager = globals
.bind::<zwp_virtual_keyboard_v1::ZwpVirtualKeyboardManagerV1, _, _>(
qh,
1..=1,
(),
)
.expect("no support virtual_keyboard");
let VirtualKeyboardSettings {
file,
keymap_size,
keymap_format,
} = settings.virtual_keyboard_support.as_ref().unwrap();
let seat = ev.get_seat();
let virtual_keyboard_in =
virtual_keyboard_manager.create_virtual_keyboard(seat, qh, ());
virtual_keyboard_in.keymap((*keymap_format).into(), file.as_fd(), *keymap_size);
ev.set_virtual_keyboard(virtual_keyboard_in);
}
}
LayerEvent::RequestMessages(message) => 'outside: {
match message {
Expand Down Expand Up @@ -355,6 +362,28 @@ where
};
window.set_size((width, height));
}
LayershellCustomActions::SetInputRegion(set_region) => {
let Some(id) = id else {
break 'out;
};
let Some(window) = ev.get_window_with_id(id) else {
break 'out;
};
let Some(region) = &wl_input_region else {
break 'out;
};

let window_size = window.get_size();
let width: i32 = window_size.0.try_into().unwrap_or_default();
let height: i32 = window_size.1.try_into().unwrap_or_default();

region.subtract(0, 0, width, height);
set_region(region);

window
.get_wlsurface()
.set_input_region(wl_input_region.as_ref());
}
LayershellCustomActions::VirtualKeyboardPressed { time, key } => {
use layershellev::reexport::wayland_client::KeyState;
let ky = ev.get_virtual_keyboard().unwrap();
Expand Down
4 changes: 4 additions & 0 deletions iced_layershell_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub fn to_layer_message(attr: TokenStream2, input: TokenStream2) -> manyhow::Res
true => {
let additional_variants = quote! {
AnchorChange{id: iced::window::Id, anchor: iced_layershell::reexport::Anchor},
SetInputRegion{ id: iced::window::Id, set_region: fn(&iced_layershell::reexport::WlRegion) },
AnchorSizeChange{id: iced::window::Id, anchor:iced_layershell::reexport::Anchor, size: (u32, u32)},
LayerChange{id: iced::window::Id, layer:iced_layershell::reexport::Layer},
MarginChange{id: iced::window::Id, margin: (i32, i32, i32, i32)},
Expand All @@ -61,6 +62,7 @@ pub fn to_layer_message(attr: TokenStream2, input: TokenStream2) -> manyhow::Res
use iced_layershell::actions::LayershellCustomActionsWithId;

match self {
Self::SetInputRegion{ id, set_region } => Ok(LayershellCustomActionsWithId::new(Some(id), LayershellCustomActions::SetInputRegion(set_region))),
Self::AnchorChange { id, anchor } => Ok(LayershellCustomActionsWithId::new(Some(id), LayershellCustomActions::AnchorChange(anchor))),
Self::AnchorSizeChange { id, anchor, size } => Ok(LayershellCustomActionsWithId::new(Some(id), LayershellCustomActions::AnchorSizeChange(anchor, size))),
Self::LayerChange { id, layer } => Ok(LayershellCustomActionsWithId::new(Some(id), LayershellCustomActions::LayerChange(layer))),
Expand Down Expand Up @@ -111,6 +113,7 @@ pub fn to_layer_message(attr: TokenStream2, input: TokenStream2) -> manyhow::Res
false => {
let additional_variants = quote! {
AnchorChange(iced_layershell::reexport::Anchor),
SetInputRegion(fn(&iced_layershell::reexport::WlRegion)),
AnchorSizeChange(iced_layershell::reexport::Anchor, (u32, u32)),
LayerChange(iced_layershell::reexport::Layer),
MarginChange((i32, i32, i32, i32)),
Expand All @@ -128,6 +131,7 @@ pub fn to_layer_message(attr: TokenStream2, input: TokenStream2) -> manyhow::Res
use iced_layershell::actions::LayershellCustomActions;

match self {
Self::SetInputRegion(region) => Ok(LayershellCustomActions::SetInputRegion(region)),
Self::AnchorChange(anchor) => Ok(LayershellCustomActions::AnchorChange(anchor)),
Self::AnchorSizeChange(anchor, size) => Ok(LayershellCustomActions::AnchorSizeChange(anchor, size)),
Self::LayerChange(layer) => Ok(LayershellCustomActions::LayerChange(layer)),
Expand Down
2 changes: 2 additions & 0 deletions layershellev/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,10 @@ pub mod reexport {
pub use wayland_client::{
globals::GlobalList,
protocol::{
wl_compositor::WlCompositor,
wl_keyboard::{self, KeyState},
wl_pointer::{self, ButtonState},
wl_region::WlRegion,
wl_seat::WlSeat,
},
QueueHandle, WEnum,
Expand Down