Skip to content

Commit df10017

Browse files
committed
chore: tidy up repo
do fmt, and README.md and etc
1 parent c58f587 commit df10017

File tree

3 files changed

+349
-1
lines changed

3 files changed

+349
-1
lines changed

iced_wayland_subscriber/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
[package]
22
name = "iced_wayland_subscriber"
3+
authors.workspace = true
34
version.workspace = true
45
edition.workspace = true
6+
license.workspace = true
7+
keywords.workspace = true
8+
repository.workspace = true
9+
readme = "README.md"
10+
description = "wayland subscriber for iced"
511

612
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
713

iced_wayland_subscriber/README.md

Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
# iced_wayland_subscriber
2+
3+
used to subscribe the wayland event
4+
5+
## Example
6+
7+
```rust
8+
use std::collections::HashMap;
9+
10+
use iced::widget::{button, column, container, row, text, text_input};
11+
use iced::window::Id;
12+
use iced::{Alignment, Element, Event, Length, Task as Command, event};
13+
use iced_layershell::actions::{IcedNewMenuSettings, IcedXdgWindowSettings, MenuDirection};
14+
use iced_runtime::window::Action as WindowAction;
15+
use iced_runtime::{Action, task};
16+
17+
use iced_layershell::daemon;
18+
use iced_layershell::reexport::{
19+
Anchor, KeyboardInteractivity, Layer, NewLayerShellSettings, OutputOption,
20+
};
21+
use iced_layershell::settings::{LayerShellSettings, Settings, StartMode};
22+
use iced_layershell::to_layer_message;
23+
use iced_wayland_subscriber::{OutputInfo, WaylandEvent};
24+
use wayland_client::Connection;
25+
26+
pub fn main() -> Result<(), iced_layershell::Error> {
27+
tracing_subscriber::fmt().init();
28+
let connection = Connection::connect_to_env().unwrap();
29+
let connection2 = connection.clone();
30+
daemon(
31+
move || Counter::new("hello", connection.clone()),
32+
Counter::namespace,
33+
Counter::update,
34+
Counter::view,
35+
)
36+
.title(Counter::title)
37+
.subscription(Counter::subscription)
38+
.settings(Settings {
39+
layer_settings: LayerShellSettings {
40+
size: Some((0, 400)),
41+
exclusive_zone: 400,
42+
anchor: Anchor::Bottom | Anchor::Left | Anchor::Right,
43+
start_mode: StartMode::AllScreens,
44+
..Default::default()
45+
},
46+
with_connection: Some(connection2),
47+
..Default::default()
48+
})
49+
.run()
50+
}
51+
52+
#[derive(Debug)]
53+
struct Counter {
54+
value: i32,
55+
text: String,
56+
ids: HashMap<iced::window::Id, WindowInfo>,
57+
connection: Connection,
58+
}
59+
60+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61+
enum WindowInfo {
62+
Left,
63+
NormalWindow,
64+
PopUp,
65+
TopBar,
66+
}
67+
68+
#[derive(Debug, Clone, Copy)]
69+
enum WindowDirection {
70+
Top(Id),
71+
Left(Id),
72+
Right(Id),
73+
Bottom(Id),
74+
}
75+
76+
#[derive(Debug, Clone)]
77+
enum WayEvent {
78+
OutputInsert(OutputInfo),
79+
#[allow(unused)]
80+
Stop(String),
81+
}
82+
83+
impl From<WaylandEvent> for WayEvent {
84+
fn from(value: WaylandEvent) -> Self {
85+
match value {
86+
WaylandEvent::Stop(e) => WayEvent::Stop(e.to_string()),
87+
WaylandEvent::OutputInsert(output) => WayEvent::OutputInsert(output),
88+
}
89+
}
90+
}
91+
92+
#[to_layer_message(multi)]
93+
#[derive(Debug, Clone)]
94+
enum Message {
95+
IncrementPressed,
96+
DecrementPressed,
97+
NewWindowLeft,
98+
NewNormalWindow,
99+
Close(Id),
100+
WindowClosed(Id),
101+
TextInput(String),
102+
Direction(WindowDirection),
103+
IcedEvent(Event),
104+
Wayland(WayEvent),
105+
}
106+
107+
impl Counter {
108+
fn window_id(&self, info: &WindowInfo) -> Option<&iced::window::Id> {
109+
for (k, v) in self.ids.iter() {
110+
if info == v {
111+
return Some(k);
112+
}
113+
}
114+
None
115+
}
116+
}
117+
118+
impl Counter {
119+
fn new(text: &str, connection: Connection) -> Self {
120+
Self {
121+
value: 0,
122+
text: text.to_string(),
123+
ids: HashMap::new(),
124+
connection,
125+
}
126+
}
127+
128+
fn title(&self, id: iced::window::Id) -> Option<String> {
129+
if let Some(WindowInfo::NormalWindow) = self.id_info(id) {
130+
return Some("hello, it is a normal window".to_owned());
131+
}
132+
None
133+
}
134+
135+
fn id_info(&self, id: iced::window::Id) -> Option<WindowInfo> {
136+
self.ids.get(&id).cloned()
137+
}
138+
139+
fn remove_id(&mut self, id: iced::window::Id) {
140+
self.ids.remove(&id);
141+
}
142+
143+
fn namespace() -> String {
144+
String::from("Counter - Iced")
145+
}
146+
147+
fn subscription(&self) -> iced::Subscription<Message> {
148+
iced::Subscription::batch(vec![
149+
event::listen().map(Message::IcedEvent),
150+
iced::window::close_events().map(Message::WindowClosed),
151+
iced_wayland_subscriber::listen(self.connection.clone())
152+
.map(|message| Message::Wayland(message.into())),
153+
])
154+
}
155+
156+
fn update(&mut self, message: Message) -> Command<Message> {
157+
use iced::Event;
158+
use iced::keyboard;
159+
use iced::keyboard::key::Named;
160+
match message {
161+
Message::WindowClosed(id) => {
162+
self.remove_id(id);
163+
Command::none()
164+
}
165+
Message::IcedEvent(event) => {
166+
match event {
167+
Event::Keyboard(keyboard::Event::KeyPressed {
168+
key: keyboard::Key::Named(Named::Escape),
169+
..
170+
}) => {
171+
if let Some(id) = self.window_id(&WindowInfo::Left) {
172+
return iced_runtime::task::effect(Action::Window(
173+
WindowAction::Close(*id),
174+
));
175+
}
176+
}
177+
Event::Mouse(iced::mouse::Event::ButtonPressed(iced::mouse::Button::Right)) => {
178+
let id = iced::window::Id::unique();
179+
self.ids.insert(id, WindowInfo::PopUp);
180+
return Command::done(Message::NewMenu {
181+
settings: IcedNewMenuSettings {
182+
size: (100, 100),
183+
direction: MenuDirection::Up,
184+
},
185+
id,
186+
});
187+
}
188+
_ => {}
189+
}
190+
Command::none()
191+
}
192+
Message::Wayland(WayEvent::OutputInsert(OutputInfo { wl_output, .. })) => {
193+
let id = iced::window::Id::unique();
194+
self.ids.insert(id, WindowInfo::TopBar);
195+
Command::done(Message::NewLayerShell {
196+
settings: NewLayerShellSettings {
197+
anchor: Anchor::Left | Anchor::Right | Anchor::Top,
198+
layer: Layer::Top,
199+
exclusive_zone: Some(30),
200+
size: Some((0, 30)),
201+
output_option: OutputOption::Output(wl_output),
202+
..Default::default()
203+
},
204+
id,
205+
})
206+
}
207+
Message::IncrementPressed => {
208+
self.value += 1;
209+
Command::none()
210+
}
211+
Message::DecrementPressed => {
212+
self.value -= 1;
213+
Command::none()
214+
}
215+
Message::TextInput(text) => {
216+
self.text = text;
217+
Command::none()
218+
}
219+
Message::Direction(direction) => match direction {
220+
WindowDirection::Left(id) => Command::done(Message::AnchorSizeChange {
221+
id,
222+
anchor: Anchor::Top | Anchor::Left | Anchor::Bottom,
223+
size: (400, 0),
224+
}),
225+
WindowDirection::Right(id) => Command::done(Message::AnchorSizeChange {
226+
id,
227+
anchor: Anchor::Top | Anchor::Right | Anchor::Bottom,
228+
size: (400, 0),
229+
}),
230+
WindowDirection::Bottom(id) => Command::done(Message::AnchorSizeChange {
231+
id,
232+
anchor: Anchor::Left | Anchor::Right | Anchor::Bottom,
233+
size: (0, 400),
234+
}),
235+
WindowDirection::Top(id) => Command::done(Message::AnchorSizeChange {
236+
id,
237+
anchor: Anchor::Left | Anchor::Right | Anchor::Top,
238+
size: (0, 400),
239+
}),
240+
},
241+
Message::NewWindowLeft => {
242+
let id = iced::window::Id::unique();
243+
self.ids.insert(id, WindowInfo::Left);
244+
Command::done(Message::NewLayerShell {
245+
settings: NewLayerShellSettings {
246+
size: Some((100, 100)),
247+
exclusive_zone: None,
248+
anchor: Anchor::Left | Anchor::Bottom,
249+
layer: Layer::Top,
250+
margin: None,
251+
keyboard_interactivity: KeyboardInteractivity::Exclusive,
252+
output_option: OutputOption::LastOutput,
253+
..Default::default()
254+
},
255+
id,
256+
})
257+
}
258+
Message::NewNormalWindow => {
259+
let (id, task) = Message::base_window_open(IcedXdgWindowSettings::default());
260+
self.ids.insert(id, WindowInfo::NormalWindow);
261+
task
262+
}
263+
Message::Close(id) => task::effect(Action::Window(WindowAction::Close(id))),
264+
_ => unreachable!(),
265+
}
266+
}
267+
268+
fn view(&self, id: iced::window::Id) -> Element<'_, Message> {
269+
if let Some(WindowInfo::Left) = self.id_info(id) {
270+
return button("close left").on_press(Message::Close(id)).into();
271+
}
272+
if let Some(WindowInfo::NormalWindow) = self.id_info(id) {
273+
return container(
274+
column![
275+
text_input("hello", &self.text)
276+
.on_input(Message::TextInput)
277+
.padding(10),
278+
button("close the normal window").on_press(Message::Close(id)),
279+
]
280+
.align_x(Alignment::Center)
281+
.padding(20),
282+
)
283+
.center_y(Length::Fill)
284+
.center_x(Length::Fill)
285+
.height(Length::Fill)
286+
.into();
287+
}
288+
if let Some(WindowInfo::TopBar) = self.id_info(id) {
289+
return text("hello here is topbar").into();
290+
}
291+
if let Some(WindowInfo::PopUp) = self.id_info(id) {
292+
return container(button("close PopUp").on_press(Message::Close(id)))
293+
.center_x(Length::Fill)
294+
.center_y(Length::Fill)
295+
.style(|_theme| container::Style {
296+
background: Some(iced::Color::from_rgba(0., 0.5, 0.7, 0.6).into()),
297+
..Default::default()
298+
})
299+
.width(Length::Fill)
300+
.height(Length::Fill)
301+
.into();
302+
}
303+
let center = column![
304+
button("Increment").on_press(Message::IncrementPressed),
305+
button("Decrement").on_press(Message::DecrementPressed),
306+
text(self.value).size(50),
307+
button("newwindowLeft").on_press(Message::NewWindowLeft),
308+
button("new normal window").on_press(Message::NewNormalWindow),
309+
]
310+
.align_x(Alignment::Center)
311+
.padding(20)
312+
.width(Length::Fill)
313+
.height(Length::Fill);
314+
row![
315+
button("left")
316+
.on_press(Message::Direction(WindowDirection::Left(id)))
317+
.height(Length::Fill),
318+
column![
319+
button("top")
320+
.on_press(Message::Direction(WindowDirection::Top(id)))
321+
.width(Length::Fill),
322+
center,
323+
text_input("hello", &self.text)
324+
.on_input(Message::TextInput)
325+
.padding(10),
326+
button("bottom")
327+
.on_press(Message::Direction(WindowDirection::Bottom(id)))
328+
.width(Length::Fill),
329+
]
330+
.width(Length::Fill),
331+
button("right")
332+
.on_press(Message::Direction(WindowDirection::Right(id)))
333+
.height(Length::Fill),
334+
]
335+
.padding(20)
336+
.spacing(10)
337+
.width(Length::Fill)
338+
.height(Length::Fill)
339+
.into()
340+
}
341+
}
342+
```

layershellev/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ use wayland_protocols::xdg::decoration::zv1::client::{
210210
pub use calloop;
211211
use calloop::{
212212
Error as CallLoopError, EventLoop, LoopHandle, RegistrationToken,
213-
channel::{self,Channel},
213+
channel::{self, Channel},
214214
timer::{TimeoutAction, Timer},
215215
};
216216
use calloop_wayland_source::WaylandSource;

0 commit comments

Comments
 (0)