summaryrefslogtreecommitdiff
path: root/src/state.rs
diff options
context:
space:
mode:
authorMaxVerevkin <maxxverrr@gmail.com>2023-01-02 20:23:35 +0200
committerMax Verevkin <34583604+MaxVerevkin@users.noreply.github.com>2023-01-02 20:44:14 +0200
commiteebeed1f2774146c3d7df90c7a982f58428d4cff (patch)
treec038e06100fbd8b4debf29c5b077d51a56a5f98b /src/state.rs
parent2570f39b5daf6e2a13b3973d47aa7c67fbb457fb (diff)
downloadi3bar-mango-eebeed1f2774146c3d7df90c7a982f58428d4cff.tar.gz
rewrite using wayrs
Diffstat (limited to 'src/state.rs')
-rw-r--r--src/state.rs713
1 files changed, 385 insertions, 328 deletions
diff --git a/src/state.rs b/src/state.rs
index e2e57ee..dbe73fd 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1,103 +1,76 @@
-use std::{future::pending, io};
+use crate::cursor::Cursor;
+use crate::protocol::*;
-use smithay_client_toolkit::{
- compositor::{CompositorHandler, CompositorState},
- delegate_compositor, delegate_layer, delegate_output, delegate_pointer, delegate_registry,
- delegate_seat, delegate_shm,
- output::{OutputHandler, OutputState},
- reexports::client::{
- protocol::{wl_output, wl_pointer, wl_seat, wl_surface},
- Connection, EventQueue, QueueHandle,
- },
- registry::{ProvidesRegistryState, RegistryState},
- registry_handlers,
- seat::{
- pointer::{PointerEvent, PointerEventKind, PointerHandler, ThemeSpec, ThemedPointer},
- Capability, SeatHandler, SeatState,
- },
- shell::layer::{
- Anchor, Layer, LayerShell, LayerShellHandler, LayerSurface, LayerSurfaceConfigure,
- },
- shm::{slot::SlotPool, ShmHandler, ShmState},
-};
-use tokio::io::unix::AsyncFdReadyGuard;
-use wayland_client::globals::GlobalList;
+use std::convert::Infallible;
+use std::future::pending;
+
+use wayrs_client::connection::Connection;
+use wayrs_client::global::{Global, GlobalExt, Globals, GlobalsExt};
+use wayrs_client::proxy::{Dispatch, Dispatcher, Proxy};
+use wayrs_shm_alloc::ShmAlloc;
use crate::{
- bar::Bar,
- config::Config,
- delegate_river_control, delegate_river_status,
- i3bar_protocol::Block,
- pointer_btn::PointerBtn,
- river_protocols::{
- control::{RiverControlHandler, RiverControlState},
- status::{RiverStatusHandler, RiverStatusState},
- },
- shared_state::SharedState,
- status_cmd::StatusCmd,
- text::ComputedText,
+ bar::Bar, config::Config, i3bar_protocol::Block, pointer_btn::PointerBtn,
+ shared_state::SharedState, status_cmd::StatusCmd, text::ComputedText,
};
pub struct State {
- registry_state: RegistryState,
- shm_state: ShmState,
- seat_state: SeatState,
- output_state: OutputState,
- compositor_state: CompositorState,
- layer_state: LayerShell,
- river_status_state: Option<RiverStatusState>,
- river_control_state: Option<RiverControlState>,
+ wl_compositor: WlCompositor,
+ layer_shell: ZwlrLayerShellV1,
+
+ river_status_manager: Option<ZriverStatusManagerV1>,
+ river_control: Option<ZriverControlV1>,
seats: Vec<Seat>,
bars: Vec<Bar>,
+
pub shared_state: SharedState,
}
struct Seat {
- seat: wl_seat::WlSeat,
- pointer: wl_pointer::WlPointer,
- themed_pointer: ThemedPointer,
- pointer_surface: wl_surface::WlSurface,
- finger_scroll: f64,
+ seat: WlSeat,
+ reg_name: u32,
+ pointer: Option<WlPointer>,
+ cursor: Cursor,
+ cur_surface: Option<WlSurface>,
+ x: f64,
+ y: f64,
+ pending_button: Option<PointerBtn>,
+ pending_scroll: f64,
+ scroll_frame: ScrollFrame,
}
impl State {
- pub fn new(event_queue: &mut EventQueue<Self>, globals: &GlobalList) -> Self {
+ pub fn new(conn: &mut Connection<Self>, globals: &Globals) -> Self {
let mut error = Ok(());
- let qh = event_queue.handle();
-
let config = Config::new()
.map_err(|e| error = Err(e))
.unwrap_or_default();
- let status_cmd = match &error {
- Err(_) => None,
- Ok(()) => config.command.as_ref().and_then(|cmd| {
- StatusCmd::new(cmd)
- .map_err(|e| error = Err(anyhow!(e)))
- .ok()
- }),
- };
+ let status_cmd = config
+ .command
+ .as_ref()
+ .and_then(|cmd| StatusCmd::new(cmd).map_err(|e| error = Err(e)).ok());
- let shm_state = ShmState::bind(globals, &qh).unwrap();
- let pool = SlotPool::new(1024, &shm_state).expect("Failed to create pool");
+ let shm = globals.bind(conn, 1..=1).expect("could not bind wl_shm");
let mut this = Self {
- registry_state: RegistryState::new(globals),
- shm_state,
- seat_state: SeatState::new(globals, &qh),
- output_state: OutputState::new(globals, &qh),
- compositor_state: CompositorState::bind(globals, &qh).unwrap(),
- layer_state: LayerShell::bind(globals, &qh).unwrap(),
- river_status_state: RiverStatusState::new(globals, &qh).ok(),
- river_control_state: RiverControlState::new(globals, &qh).ok(),
+ wl_compositor: globals
+ .bind(conn, 4..=5)
+ .expect("could not bind wl_compositor"),
+ layer_shell: globals
+ .bind(conn, 1..=4)
+ .expect("could not bind layer_shell"),
+
+ river_status_manager: globals.bind(conn, 1..=4).ok(),
+ river_control: globals.bind(conn, 1..=1).ok(),
seats: Vec::new(),
bars: Vec::new(),
+
shared_state: SharedState {
- qh: event_queue.handle(),
- pool,
+ shm: ShmAlloc::new(conn, shm, 1024),
config,
status_cmd,
blocks: Vec::new(),
@@ -105,113 +78,102 @@ impl State {
},
};
+ globals
+ .iter()
+ .filter(|g| g.is::<WlSeat>())
+ .for_each(|g| this.bind_seat(conn, g));
+ globals
+ .iter()
+ .filter(|g| g.is::<WlOutput>())
+ .for_each(|g| this.bind_output(conn, g));
+
if let Err(e) = error {
- this.set_error(e.to_string());
+ this.set_error(conn, e.to_string());
}
this
}
- pub fn set_blocks(&mut self, blocks: Vec<Block>) {
+ pub fn set_blocks(&mut self, conn: &mut Connection<Self>, blocks: Vec<Block>) {
self.shared_state.blocks = blocks;
- self.draw_all();
+ self.draw_all(conn);
}
- pub fn set_error(&mut self, error: impl Into<String>) {
- self.set_blocks(vec![Block {
- full_text: error.into(),
- ..Default::default()
- }]);
+ pub fn set_error(&mut self, conn: &mut Connection<Self>, error: impl Into<String>) {
+ self.set_blocks(
+ conn,
+ vec![Block {
+ full_text: error.into(),
+ ..Default::default()
+ }],
+ );
}
- pub fn notify_available(&mut self) -> anyhow::Result<()> {
- if let Some(cmd) = &mut self.shared_state.status_cmd {
- if let Some(blocks) = cmd.notify_available()? {
- self.set_blocks(blocks);
- }
- }
- Ok(())
- }
-
- pub fn draw_all(&mut self) {
+ pub fn draw_all(&mut self, conn: &mut Connection<Self>) {
for bar in &mut self.bars {
- bar.draw(&mut self.shared_state);
+ bar.request_frame(conn);
}
}
- pub async fn wait_for_status_cmd(&self) -> io::Result<AsyncFdReadyGuard<i32>> {
- match &self.shared_state.status_cmd {
- Some(cmd) => cmd.async_fd.readable().await,
+ pub async fn status_cmd_read(&mut self) -> anyhow::Result<()> {
+ match &mut self.shared_state.status_cmd {
+ Some(cmd) => cmd.read().await,
None => {
pending::<()>().await;
unreachable!()
}
}
}
-}
-impl CompositorHandler for State {
- fn scale_factor_changed(
+ pub fn status_cmd_notify_available(
&mut self,
- _conn: &Connection,
- _qh: &QueueHandle<Self>,
- surface: &wl_surface::WlSurface,
- scale: i32,
- ) {
- if let Some(bar) = self
- .bars
- .iter_mut()
- .find(|bar| bar.layer.wl_surface() == surface)
- {
- bar.scale = scale;
- bar.draw(&mut self.shared_state);
+ conn: &mut Connection<Self>,
+ ) -> anyhow::Result<()> {
+ if let Some(cmd) = &mut self.shared_state.status_cmd {
+ if let Some(blocks) = cmd.notify_available()? {
+ self.set_blocks(conn, blocks);
+ }
}
+ Ok(())
}
- fn frame(
- &mut self,
- _conn: &Connection,
- _qh: &QueueHandle<Self>,
- _surface: &wl_surface::WlSurface,
- _time: u32,
- ) {
- }
-}
+ fn bind_output(&mut self, conn: &mut Connection<Self>, global: &Global) {
+ let output = global.bind(conn, 2..=4).expect("could not bind wl_output");
+ let surface = self.wl_compositor.create_surface(conn);
-impl OutputHandler for State {
- fn output_state(&mut self) -> &mut OutputState {
- &mut self.output_state
- }
+ use zwlr_layer_shell_v1::Layer;
+ use zwlr_layer_surface_v1::Anchor;
+ let layer_surface = self.layer_shell.get_layer_surface(
+ conn,
+ surface,
+ output,
+ Layer::Top,
+ wayrs_client::cstr!("i3bar-river").into(),
+ );
+ layer_surface.set_size(conn, 0, self.shared_state.config.height);
+ layer_surface.set_anchor(conn, Anchor::Top | Anchor::Left | Anchor::Right); // Top + Left + Right
+ layer_surface.set_exclusive_zone(conn, self.shared_state.config.height as i32 + 5); // TODO: make the margin configurable
+
+ // Note: layer_surface is commited when we receive the scale factor of this output
- fn new_output(
- &mut self,
- _conn: &Connection,
- qh: &QueueHandle<Self>,
- output: wl_output::WlOutput,
- ) {
- let height = self.shared_state.config.height;
- let surface = self.compositor_state.create_surface(qh);
- let layer = LayerSurface::builder()
- .output(&output)
- .size((0, height))
- .anchor(Anchor::TOP | Anchor::LEFT | Anchor::RIGHT)
- .namespace("i3bar-river")
- .map(qh, &self.layer_state, surface, Layer::Top)
- .expect("layer surface creation");
let river_output_status = self
- .river_status_state
- .as_mut()
- .map(|s| s.new_output_status(qh, &output));
+ .river_status_manager
+ .as_ref()
+ .map(|s| s.get_river_output_status(conn, output));
+
self.bars.push(Bar {
output,
+ output_reg_name: global.name,
configured: false,
+ frame_cb: None,
width: 0,
- height,
+ height: self.shared_state.config.height,
scale: 1,
- layer,
+ surface,
+ layer_surface,
blocks_btns: Default::default(),
river_output_status,
- river_control: self.river_control_state.clone(),
+ river_control: self.river_control,
layout_name: None,
layout_name_computed: None,
tags_btns: Default::default(),
@@ -220,238 +182,318 @@ impl OutputHandler for State {
});
}
- fn update_output(
- &mut self,
- _conn: &Connection,
- _qh: &QueueHandle<Self>,
- _output: wl_output::WlOutput,
- ) {
+ fn bind_seat(&mut self, conn: &mut Connection<Self>, global: &Global) {
+ let seat: WlSeat = global.bind(conn, 5..=8).unwrap();
+ let cursor = Cursor::new(conn, self.wl_compositor).unwrap();
+ self.seats.push(Seat {
+ seat,
+ reg_name: global.name,
+ pointer: None,
+ cursor,
+ cur_surface: None,
+ x: 0.0,
+ y: 0.0,
+ pending_button: None,
+ pending_scroll: 0.0,
+ scroll_frame: ScrollFrame::default(),
+ });
}
- fn output_destroyed(
- &mut self,
- _conn: &Connection,
- _qh: &QueueHandle<Self>,
- _output: wl_output::WlOutput,
- ) {
+ fn drop_bar(&mut self, conn: &mut Connection<Self>, bar_index: usize) {
+ let bar = self.bars.swap_remove(bar_index);
+ bar.surface.destroy(conn);
+ bar.layer_surface.destroy(conn);
+ if let Some(output_status) = bar.river_output_status {
+ output_status.destroy(conn);
+ }
+ if bar.output.version() >= 3 {
+ bar.output.release(conn);
+ }
}
-}
-impl LayerShellHandler for State {
- fn closed(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, layer: &LayerSurface) {
- self.bars.retain(|b| &b.layer != layer)
+ fn drop_seat(&mut self, conn: &mut Connection<Self>, seat_index: usize) {
+ let seat = self.seats.swap_remove(seat_index);
+ if let Some(pointer) = seat.pointer {
+ if pointer.version() >= 3 {
+ pointer.release(conn);
+ }
+ }
+ if seat.seat.version() >= 5 {
+ seat.seat.release(conn);
+ }
}
+}
- fn configure(
- &mut self,
- _conn: &Connection,
- _qh: &QueueHandle<Self>,
- layer: &LayerSurface,
- configure: LayerSurfaceConfigure,
- _serial: u32,
- ) {
- self.bars
- .iter_mut()
- .find(|b| &b.layer == layer)
- .unwrap()
- .configure(&mut self.shared_state, configure.new_size.0);
- }
+impl Dispatcher for State {
+ type Error = Infallible;
}
-impl SeatHandler for State {
- fn seat_state(&mut self) -> &mut SeatState {
- &mut self.seat_state
+impl Dispatch<WlRegistry> for State {
+ fn event(&mut self, conn: &mut Connection<Self>, _: WlRegistry, event: wl_registry::Event) {
+ match event {
+ wl_registry::Event::Global(global) if global.is::<WlOutput>() => {
+ self.bind_output(conn, &global);
+ }
+ wl_registry::Event::Global(global) if global.is::<WlSeat>() => {
+ self.bind_seat(conn, &global);
+ }
+ wl_registry::Event::GlobalRemove(name) => {
+ if let Some(bar_index) =
+ self.bars.iter().position(|bar| bar.output_reg_name == name)
+ {
+ self.drop_bar(conn, bar_index);
+ } else if let Some(seat_index) =
+ self.seats.iter().position(|seat| seat.reg_name == name)
+ {
+ self.drop_seat(conn, seat_index);
+ }
+ }
+ _ => (),
+ }
}
+}
- fn new_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
+impl Dispatch<WlCallback> for State {
+ fn event(&mut self, conn: &mut Connection<Self>, cb: WlCallback, event: wl_callback::Event) {
+ let wl_callback::Event::Done(_) = event;
+ if let Some(bar) = self.bars.iter_mut().find(|bar| bar.frame_cb == Some(cb)) {
+ bar.frame_cb = None;
+ bar.frame(conn, &mut self.shared_state);
+ }
+ }
+}
- fn new_capability(
- &mut self,
- _conn: &Connection,
- qh: &QueueHandle<Self>,
- seat: wl_seat::WlSeat,
- capability: Capability,
- ) {
- if capability == Capability::Pointer {
- let (pointer, themed_pointer) = self
- .seat_state
- .get_pointer_with_theme(qh, &seat, ThemeSpec::System, 1)
- .expect("Failed to create pointer");
- self.seats.push(Seat {
- seat,
- pointer,
- themed_pointer,
- pointer_surface: self.compositor_state.create_surface(qh),
- finger_scroll: 0.0,
- });
+impl Dispatch<WlOutput> for State {
+ fn event(&mut self, conn: &mut Connection<Self>, output: WlOutput, event: wl_output::Event) {
+ if let wl_output::Event::Scale(scale) = event {
+ let bar = self
+ .bars
+ .iter_mut()
+ .find(|bar| bar.output == output)
+ .unwrap();
+ bar.scale = scale;
+ // If bar is not configured yet, it is because we were waiting for the "scale" event
+ // before commiting the surface. Otherwise, there is no need to do any redrawing (we'll
+ // do that after "configure" event).
+ if !bar.configured {
+ bar.surface.commit(conn);
+ }
}
}
+}
- fn remove_capability(
+impl Dispatch<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1> for State {
+ fn event(
&mut self,
- _conn: &Connection,
- _qh: &QueueHandle<Self>,
- seat: wl_seat::WlSeat,
- capability: Capability,
+ conn: &mut Connection<Self>,
+ layer_surface: zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
+ event: zwlr_layer_surface_v1::Event,
) {
- if capability == Capability::Pointer {
- self.seats.retain(|p| p.seat == seat);
+ match event {
+ zwlr_layer_surface_v1::Event::Configure(args) => {
+ let bar = self
+ .bars
+ .iter_mut()
+ .find(|bar| bar.layer_surface == layer_surface)
+ .unwrap();
+ assert_ne!(args.width, 0);
+ bar.width = args.width;
+ bar.configured = true;
+ bar.layer_surface.ack_configure(conn, args.serial);
+ bar.frame(conn, &mut self.shared_state);
+ }
+ zwlr_layer_surface_v1::Event::Closed => {
+ let bar_index = self
+ .bars
+ .iter()
+ .position(|bar| bar.layer_surface == layer_surface)
+ .unwrap();
+ self.drop_bar(conn, bar_index);
+ }
}
}
+}
- fn remove_seat(&mut self, _: &Connection, _: &QueueHandle<Self>, _: wl_seat::WlSeat) {}
+impl Dispatch<WlBuffer> for State {
+ fn event(&mut self, _: &mut Connection<Self>, buffer: WlBuffer, event: wl_buffer::Event) {
+ let wl_buffer::Event::Release = event;
+ self.shared_state.shm.free_buffer(buffer);
+ }
}
-impl PointerHandler for State {
- fn pointer_frame(
- &mut self,
- conn: &Connection,
- _qh: &QueueHandle<Self>,
- pointer: &wl_pointer::WlPointer,
- events: &[PointerEvent],
- ) {
+impl Dispatch<WlSeat> for State {
+ fn event(&mut self, conn: &mut Connection<Self>, seat: WlSeat, event: wl_seat::Event) {
+ if let wl_seat::Event::Capabilities(capabilities) = event {
+ let seat = self.seats.iter_mut().find(|s| s.seat == seat).unwrap();
+ match &seat.pointer {
+ Some(pointer) if !capabilities.contains(wl_seat::Capability::Pointer) => {
+ if pointer.version() >= 3 {
+ pointer.release(conn);
+ }
+ seat.pointer = None;
+ }
+ None if capabilities.contains(wl_seat::Capability::Pointer) => {
+ let pointer = seat.seat.get_pointer(conn);
+ seat.pointer = Some(pointer);
+ }
+ _ => (),
+ }
+ }
+ }
+}
+
+impl Dispatch<WlPointer> for State {
+ fn event(&mut self, conn: &mut Connection<Self>, pointer: WlPointer, event: wl_pointer::Event) {
let seat = self
.seats
.iter_mut()
- .find(|p| &p.pointer == pointer)
+ .find(|s| s.pointer == Some(pointer))
.unwrap();
- for event in events {
- if let Some(bar) = self
- .bars
- .iter_mut()
- .find(|b| b.layer.wl_surface() == &event.surface)
- {
- match event.kind {
- PointerEventKind::Enter { .. } => {
- seat.themed_pointer
- .set_cursor(
- conn,
- "default",
- self.shm_state.wl_shm(),
- &seat.pointer_surface,
- )
+
+ use wl_pointer::Event;
+ match event {
+ Event::Frame => {
+ let btn = seat.pending_button.take();
+ let scroll = seat.scroll_frame.finalize();
+ if let Some(surface) = seat.cur_surface {
+ let bar = self
+ .bars
+ .iter_mut()
+ .find(|bar| bar.surface == surface)
+ .unwrap();
+
+ if let Some(btn) = btn {
+ bar.click(conn, &mut self.shared_state, btn, seat.seat, seat.x, seat.y)
.unwrap();
}
- PointerEventKind::Press { button, .. } => {
- bar.click(
- &mut self.shared_state,
- button.into(),
- &seat.seat,
- event.position.0,
- event.position.1,
- )
- .unwrap();
+
+ if scroll.is_finder && self.shared_state.config.invert_touchpad_scrolling {
+ seat.pending_scroll -= scroll.absolute;
+ } else {
+ seat.pending_scroll += scroll.absolute;
+ }
+
+ if scroll.stop {
+ seat.pending_scroll = 0.0;
}
- PointerEventKind::Axis {
- vertical, source, ..
- } => {
- if source == Some(wl_pointer::AxisSource::Finger) {
- if self.shared_state.config.invert_touchpad_scrolling {
- seat.finger_scroll -= vertical.absolute;
- } else {
- seat.finger_scroll += vertical.absolute;
- }
- if vertical.stop {
- seat.finger_scroll = 0.0;
- }
- }
- let btn = if vertical.discrete > 0 {
- PointerBtn::WheelDown
- } else if vertical.discrete < 0 {
- PointerBtn::WheelUp
- } else if seat.finger_scroll >= 15.0 {
- seat.finger_scroll = 0.0;
- PointerBtn::WheelDown
- } else if seat.finger_scroll <= -15.0 {
- seat.finger_scroll = 0.0;
- PointerBtn::WheelUp
- } else {
- continue;
- };
+ let btn = if seat.pending_scroll >= 15.0 {
+ seat.pending_scroll = 0.0;
+ Some(PointerBtn::WheelDown)
+ } else if seat.pending_scroll <= -15.0 {
+ seat.pending_scroll = 0.0;
+ Some(PointerBtn::WheelUp)
+ } else {
+ None
+ };
- bar.click(
- &mut self.shared_state,
- btn,
- &seat.seat,
- event.position.0,
- event.position.1,
- )
- .unwrap();
+ if let Some(btn) = btn {
+ bar.click(conn, &mut self.shared_state, btn, seat.seat, seat.x, seat.y)
+ .unwrap();
}
- _ => (),
}
}
+ Event::Enter(args) => {
+ let bar = self
+ .bars
+ .iter()
+ .find(|bar| bar.surface.id() == args.surface)
+ .unwrap();
+ seat.cur_surface = Some(bar.surface);
+ seat.x = args.surface_x.as_f64();
+ seat.y = args.surface_y.as_f64();
+ seat.cursor.set(
+ conn,
+ args.serial,
+ pointer,
+ bar.scale as u32,
+ &mut self.shared_state.shm,
+ );
+ }
+ Event::Leave(_) => seat.cur_surface = None,
+ Event::Motion(args) => {
+ seat.x = args.surface_x.as_f64();
+ seat.y = args.surface_y.as_f64();
+ }
+ Event::Button(args) => {
+ if args.state == wl_pointer::ButtonState::Pressed {
+ seat.pending_button = Some(args.button.into());
+ }
+ }
+ Event::Axis(args) => {
+ if args.axis == wl_pointer::Axis::VerticalScroll {
+ seat.scroll_frame.absolute += args.value.as_f64();
+ }
+ }
+ Event::AxisSource(source) => {
+ seat.scroll_frame.is_finder = source == wl_pointer::AxisSource::Finger;
+ }
+ Event::AxisStop(args) => {
+ if args.axis == wl_pointer::Axis::VerticalScroll {
+ seat.scroll_frame.stop = true;
+ }
+ }
+ Event::AxisDiscrete(_) | Event::AxisValue120(_) => (),
}
}
}
-impl ShmHandler for State {
- fn shm_state(&mut self) -> &mut ShmState {
- &mut self.shm_state
- }
-}
-
-impl RiverStatusHandler for State {
- fn river_status_state(&mut self) -> &mut RiverStatusState {
- self.river_status_state.as_mut().unwrap()
- }
-
- fn focused_tags_updated(&mut self, output: &wl_output::WlOutput, focused: u32) {
- let bar = self.bars.iter_mut().find(|b| &b.output == output).unwrap();
- bar.tags_info.focused = focused;
- bar.draw(&mut self.shared_state);
- }
-
- fn urgent_tags_updated(&mut self, output: &wl_output::WlOutput, urgent: u32) {
- let bar = self.bars.iter_mut().find(|b| &b.output == output).unwrap();
- bar.tags_info.urgent = urgent;
- bar.draw(&mut self.shared_state);
- }
+impl Dispatch<ZriverOutputStatusV1> for State {
+ fn event(
+ &mut self,
+ conn: &mut Connection<Self>,
+ status: ZriverOutputStatusV1,
+ event: zriver_output_status_v1::Event,
+ ) {
+ let bar = self
+ .bars
+ .iter_mut()
+ .find(|b| b.river_output_status == Some(status))
+ .unwrap();
- fn views_tags_updated(&mut self, output: &wl_output::WlOutput, tags: Vec<u32>) {
- let bar = self.bars.iter_mut().find(|b| &b.output == output).unwrap();
- bar.tags_info.active = tags.into_iter().fold(0, |a, b| a | b);
- bar.draw(&mut self.shared_state);
- }
+ use zriver_output_status_v1::Event;
+ match event {
+ Event::FocusedTags(tags) => bar.tags_info.focused = tags,
+ Event::UrgentTags(tags) => bar.tags_info.urgent = tags,
+ Event::LayoutName(name) => bar.set_layout_name(Some(name.into_string().unwrap())),
+ Event::LayoutNameClear => bar.set_layout_name(None),
+ Event::ViewTags(vt) => {
+ bar.tags_info.active = vt
+ .chunks_exact(4)
+ .map(|bytes| u32::from_ne_bytes(bytes.try_into().unwrap()))
+ .fold(0, |a, b| a | b);
+ }
+ }
- fn layout_name_updated(&mut self, output: &wl_output::WlOutput, layout_name: Option<String>) {
- let bar = self.bars.iter_mut().find(|b| &b.output == output).unwrap();
- bar.set_layout_name(layout_name);
- bar.draw(&mut self.shared_state);
+ bar.request_frame(conn);
}
}
-impl RiverControlHandler for State {
- fn river_control_state(&mut self) -> &mut RiverControlState {
- self.river_control_state.as_mut().unwrap()
- }
-
- fn command_failure(&mut self, _: &Connection, _: &QueueHandle<Self>, message: String) {
- self.set_error(format!("[river_control] {message}"));
- }
-
- fn command_success(&mut self, _: &Connection, _: &QueueHandle<Self>, message: String) {
- info!("river_control: {message}");
+impl Dispatch<ZriverCommandCallbackV1> for State {
+ fn event(
+ &mut self,
+ conn: &mut Connection<Self>,
+ _: ZriverCommandCallbackV1,
+ event: zriver_command_callback_v1::Event,
+ ) {
+ use zriver_command_callback_v1::Event;
+ match event {
+ Event::Success(msg) => info!("river_control: {msg:?}"),
+ Event::Failure(msg) => self.set_error(conn, msg.into_string().unwrap()),
+ }
}
}
-delegate_compositor!(State);
-delegate_output!(State);
-delegate_shm!(State);
-delegate_seat!(State);
-delegate_pointer!(State);
-delegate_layer!(State);
-delegate_registry!(State);
-delegate_river_status!(State);
-delegate_river_control!(State);
+// Interfaces with no events
+impl Dispatch<WlCompositor> for State {}
+impl Dispatch<ZwlrLayerShellV1> for State {}
+impl Dispatch<ZriverStatusManagerV1> for State {}
+impl Dispatch<ZriverControlV1> for State {}
+impl Dispatch<WlShmPool> for State {}
-impl ProvidesRegistryState for State {
- fn registry(&mut self) -> &mut RegistryState {
- &mut self.registry_state
- }
- registry_handlers![OutputState,];
-}
+// Dont care
+impl Dispatch<WlShm> for State {}
+impl Dispatch<WlSurface> for State {}
#[derive(Debug)]
pub struct ComputedBlock {
@@ -460,3 +502,18 @@ pub struct ComputedBlock {
pub short: Option<ComputedText>,
pub min_width: Option<f64>,
}
+
+#[derive(Debug, Default, Clone, Copy)]
+pub struct ScrollFrame {
+ stop: bool,
+ absolute: f64,
+ is_finder: bool,
+}
+
+impl ScrollFrame {
+ fn finalize(&mut self) -> Self {
+ let copy = *self;
+ *self = Self::default();
+ copy
+ }
+}