Skip to main content
  1. Posts/

River Protocol & Architecture

·1226 words·6 mins·
ebeem
Author
ebeem
FOSS Enthusiast & Indie Game Developer

I’m currently studying River in the hope of crafting a guile scheme based window manager, River uses a unique non-monolithic approach, unlike the "all-in-one" approach seen in many compositors, it splits the responsibilities of rendering and window management.

I am using this post as a living document to log my notes and findings as I study the river-window-management-v1 protocol. One done, it should be a great foundation for those who want to understand my window manager or write their own based on River.

interfaces

river_window_manager_v1

Window management state influences the communication between the compositor and individual windows (e.g. xdg_toplevels). Window management state includes window dimensions, fullscreen state, keyboard focus, keyboard bindings, and more.Only one window management client may be active at a time. The compositor should use the unavailable event if necessary to enforce this.

requests

  • (2) stop

description: client wants to stop/close

task: Nothing, wait for finished event to proceed with killing the process

  • (4) destroy()

description: should be called after the finished event has been received.

task: clear anything that's still references and terminate

  • (6) manage_finish()

description: client has made all changes to window management state after receiving the manage_start event

task: Nothing, don't send any requests to change window management state unless you receive another manage_start

  • (7) manage_dirty()

description: indicates that a manage_sequence events is needed to reflect some new state changes

task: Nothing, you will receive a manage_start soon to make the changes as before

  • (9) render_finish()

description: client has made all changes to rendering state after receiving the render_start event

task: Nothing, don't send any requests to change render state unless you receive another manage_start or manage_render

  • (15) get_shell_surface(surface: wl_surface) -> id: river_shell_surface_v1

description: client wants to create a new shell surface and assign river_shell_surface_v1 role to provided surface, it can be used to draw status bars, menus, tab bar, etc.

task: Nothing

  • (16) exit_session()

description: client wants to terminal the wayland session, this will close all clients and the compositor

task: Nothing

events

  • (1) unavailable()

description: indicates that window management is unavailable, most likely due to another window management client already running

task: The client should clear everything in this case and terminate

  • (3) finished()

description: indicates that the server will send no longer events

task: The client should clear everything in this case and send destroy request

  • (5) manage_start()

description: indicates that the server has sent events indicating new state changes

task: The client should send all requesting modfying the window management state then make a manage_finish request

  • (8) render_start()

description: indicates that the server has sent events indicating window positions and dimensions changes in the interface river_window_v1

task: The client should send all requesting modfying the rendering state then make a render_finish request

  • (10) session_locked()

description: indicates that the session has been locked

task: The client should most likely may restrict the available keybindings or call a lock screen application

  • (11) session_unlocked()

description: indicates that the session has been unlocked

task: The client should most likely may reinitiate the available keybindings

  • (12) window() -> id: river_window_v1

description: indicates that a new has been created.

task: store the id/proxy and mapping for further use

  • (13) output() -> id: river_output_v1

description: indicates that a output has been created (monitor plugged)

task: store the id/proxy and mapping for further use

  • (14) seat() -> id: river_seat_v1

description: indicates that a seat/input has been created (keyboard/mouse/touchscreen plugged)

task: store the id/proxy and mapping for further use

river_window_v1

Logical window. For example, a window may correspond to an xdg_toplevel or Xwayland window. A newly created window will not be displayed until the window manager makes a propose_dimensions or fullscreen request as part of a render_sequence

requests

  • (1) close()

description: client want the window to be closed, window may ignore this request

task: wait for closed

  • (3) destroy()

description: client cleaned window object and it can be safely destroyed

task: nothing

  • (4) get_node() -> id: river_node_v1

description: client wants to know the node that corresponds to the window, this can only be called once per node, so it should be cached after first call.

task: store it as metadata of the window record/object

  • (7) propose_dimensions(width: int, height: int)

description: client proposes dimensions for the window.

task: only send in manage_sequence as it modifies the window management state, wait for dimensions event for confirmation about the update

  • (8) hide()

description: client wants to hide a window (newly created windows are shown by default).

task: only send in render_sequence as it modifies the rendering state.

  • (9) show()

description: client wants to show a window, care about windows that are placed on top of it as they will not make the target window visible.

task: only send in render_sequence as it modifies the rendering state.

  • (15) use_csd()

description: client wants to use client side decoration (default).

task: only send in manage_sequence as it modifies the window management state.

  • (16) use_ssd()

description: tell the client to use server side decoration

task: only send in manage_sequence as it modifies the window management state.

  • (17) set_borders(edges: uint, width: int, r: uint, g: uint, b: uint,

a:uint)

description: decorates the window with borders drawn by the compositor

task: only send in render_sequence as it modifies the rendering state.

  • (18) set_tiled(edges: uint)

description: inform the window that it is part of a tiled layout

task: only send in manage_sequence as it modifies the window management state.

  • (19) get_decoration_above(surface: wl_surface) -> id: river_decoration_v1

description: inform the window that it is part of a tiled layout

task: only send in manage_sequence as it modifies the window management state.

events

  • (2) closed()

description: indicates that the window has been closed

task: clean window and send destroy

  • (5) dimensions_hint(min_width: int, min_height: int, max_width: int,

max_height: int)

description: indicates the window's preferred min/max dimensions (excluding borders and decorations). The window manager is free to propose other dimensions for layouts that require it like tiling.

task: store the preferred dimensions in window object/record for further use. This event will be followed by manage_start and state changes should be made there.

  • (6) dimensions(width: int, height: int)

description: indicates the window's dimensions (excluding borders and decorations). This event is sent as part of the render_sequence due to propose_dimensions or fullscreen request

task: store the dimensions in window object/record for further use. This event will be followed by render_start and state changes should be made there.

  • (10) app_id(app_id: string?)

description: indicates the window's application id was changed

task: store the app_id in window object/record for further use. This will be followed by a manage_sequence in case state changes need to be made.

  • (11) title(title: string?)

description: indicates the window's title was changed

task: store the title in window object/record for further use. This will be followed by a manage_sequence in case state changes need to be made.

  • (12) parent(parent: river_window_v1?)

description: indicates the window's parent was changed

task: store the parent in window object/record for further use. This will be followed by a manage_sequence in case state changes need to be made.

  • (13) decoration_hint(hint: uint)

description: indicates the window's parent was changed

task: store the hint in window object/record for further use. This will be followed by a manage_sequence in case state changes need to be made.

  • (14) decoration_hint(hint: uint)

description: indicates the window's parent was changed

task: store the hint in window object/record for further use. This will be followed by a manage_sequence in case state changes need to be made.