commit 0fbf25d214e7ba98f0c0e773f49409fee3523437 Author: Makesesama Date: Thu May 1 13:53:39 2025 +0200 init diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/bar/__init__.py b/bar/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bar/bar.css b/bar/bar.css new file mode 100644 index 0000000..a467910 --- /dev/null +++ b/bar/bar.css @@ -0,0 +1,173 @@ +/* Fabric bar.css + * https://github.com/Fabric-Development/fabric/blob/rewrite/examples/bar/bar.css + */ + +/* we can use webcss variables, fabric compiles that to gtk css. + global variables can be stored in :vars */ +:vars { + --background: #150d16; + --foreground: #f5dbc4; + --color0: #150d16; + --color1: #72448D; + --color2: #9C5995; + --color3: #D5719F; + --color4: #9A62F3; + --color5: #E075DF; + --color6: #F98F9F; + --color7: #f5dbc4; + --color8: #ab9989; + --color9: #72448D; + --color10: #9C5995; + --color11: #D5719F; + --color12: #9A62F3; + --color13: #E075DF; + --color14: #F98F9F; + --color15: #f5dbc4; + --window-bg: alpha(var(--background), 0.6); + --module-bg: alpha(var(--background), 0.4); + --border-color: var(--color11); + --ws-active: var(--color9); + --ws-inactive: var(--color3); + --ws-empty: var(--color8); + --ws-hover: var(--color1); + --ws-urgent: var(--color12); +} + +/* unset so we can style everything from the ground up. */ +* { + all: unset; + color: var(--foreground); + font-size: 16px; + font-family: "Jost*", sans-serif; + border-radius: 100px; +} + +button { + background-size: 400% 400%; +} + +#bar-inner { + padding: 4px; + border: solid 2px; + border-color: var(--border-color); + background-color: var(--window-bg); + min-height: 28px; +} + +#workspaces { + padding: 6px; + min-width: 0px; + background-color: var(--module-bg); +} + +#workspaces>button { + padding: 0px 8px; + transition: padding 0.05s steps(8); + background-color: var(--ws-inactive); +} + +#workspaces>button>label { + font-size: 0px; +} + +#workspaces>button:hover { + background-color: var(--ws-hover); +} + +#workspaces>button.urgent { + background-color: var(--ws-urgent); +} + +#workspaces>button.active { + padding: 0px 32px; + background-color: var(--ws-active); +} + +#workspaces>button.empty { + background-color: var(--ws-empty); +} + + +#date-time, +#hyprland-language, +#hyprland-window { + background-color: var(--module-bg); + padding: 0px 8px; +} + +menu>menuitem>label, +#date-time>label, +#hyprland-language>label, +#hyprland-window>label { + font-weight: 900; +} + +/* system tray */ +#system-tray { + padding: 2px 4px; + background-color: var(--module-bg); +} + +/* menu and menu items (written for the system tray) */ +menu { + border: solid 2px; + border-radius: 10px; + border-color: var(--border-color); + background-color: var(--window-bg); +} + +menu>menuitem { + border-radius: 0px; + background-color: var(--module-bg); + padding: 6px; + margin-left: 2px; + margin-right: 2px; +} + +menu>menuitem:first-child { + margin-top: 1px; + border-radius: 8px 8px 0px 0px; +} + +menu>menuitem:last-child { + margin-bottom: 1px; + border-radius: 0px 0px 8px 8px; +} + +menu>menuitem:hover { + background-color: var(--border-color); +} + + +#cpu-progress-bar, +#ram-progress-bar, +#volume-progress-bar { + color: transparent; + background-color: transparent +} + + +#cpu-progress-bar { + border: solid 0px alpha(var(--color9), 0.8); +} + +#ram-progress-bar, +#volume-progress-bar { + border: solid 0px var(--border-color); +} + + +#widgets-container { + background-color: var(--module-bg); + padding: 2px; +} + +tooltip { + border: solid 2px; + border-color: var(--border-color); + background-color: var(--window-bg); +} + +tooltip>* { + padding: 2px 4px +} diff --git a/bar/bar.py b/bar/bar.py new file mode 100644 index 0000000..b421d26 --- /dev/null +++ b/bar/bar.py @@ -0,0 +1,162 @@ +# fabric bar.py example +# https://github.com/Fabric-Development/fabric/blob/rewrite/examples/bar/bar.py +import psutil +from fabric import Application +from fabric.widgets.box import Box +from fabric.widgets.label import Label +from fabric.widgets.overlay import Overlay +from fabric.widgets.eventbox import EventBox +from fabric.widgets.datetime import DateTime +from fabric.widgets.centerbox import CenterBox +from fabric.system_tray.widgets import SystemTray +from fabric.widgets.circularprogressbar import CircularProgressBar +from fabric.widgets.wayland import WaylandWindow as Window +from .river.widgets import RiverWorkspaces, RiverWorkspaceButton +from fabric.utils import ( + FormattedString, + bulk_replace, + invoke_repeater, + get_relative_path, +) + +AUDIO_WIDGET = True + +if AUDIO_WIDGET is True: + try: + from fabric.audio.service import Audio + except Exception as e: + print(e) + AUDIO_WIDGET = False + + +class VolumeWidget(Box): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.audio = Audio() + + self.progress_bar = CircularProgressBar( + name="volume-progress-bar", pie=True, size=24 + ) + + self.event_box = EventBox( + events="scroll", + child=Overlay( + child=self.progress_bar, + overlays=Label( + label="", + style="margin: 0px 6px 0px 0px; font-size: 12px", # to center the icon glyph + ), + ), + ) + + self.audio.connect("notify::speaker", self.on_speaker_changed) + self.event_box.connect("scroll-event", self.on_scroll) + self.add(self.event_box) + + def on_scroll(self, _, event): + match event.direction: + case 0: + self.audio.speaker.volume += 8 + case 1: + self.audio.speaker.volume -= 8 + return + + def on_speaker_changed(self, *_): + if not self.audio.speaker: + return + self.progress_bar.value = self.audio.speaker.volume / 100 + self.audio.speaker.bind( + "volume", "value", self.progress_bar, lambda _, v: v / 100 + ) + return + + +class StatusBar(Window): + def __init__( + self, + ): + super().__init__( + name="bar", + layer="top", + anchor="left top right", + margin="10px 10px -2px 10px", + exclusivity="auto", + visible=False, + all_visible=False, + ) + self.workspaces = RiverWorkspaces( + 44, + name="workspaces", + spacing=4, + buttons_factory=lambda ws_id: RiverWorkspaceButton(id=ws_id, label=None), + ) + self.date_time = DateTime(name="date-time") + self.system_tray = SystemTray(name="system-tray", spacing=4) + + self.ram_progress_bar = CircularProgressBar( + name="ram-progress-bar", pie=True, size=24 + ) + self.cpu_progress_bar = CircularProgressBar( + name="cpu-progress-bar", pie=True, size=24 + ) + self.progress_bars_overlay = Overlay( + child=self.ram_progress_bar, + overlays=[ + self.cpu_progress_bar, + Label("", style="margin: 0px 6px 0px 0px; font-size: 12px"), + ], + ) + + self.status_container = Box( + name="widgets-container", + spacing=4, + orientation="h", + children=self.progress_bars_overlay, + ) + self.status_container.add(VolumeWidget()) if AUDIO_WIDGET is True else None + + self.children = CenterBox( + name="bar-inner", + start_children=Box( + name="start-container", + spacing=4, + orientation="h", + children=self.workspaces, + ), + center_children=Box( + name="center-container", + spacing=4, + orientation="h", + ), + end_children=Box( + name="end-container", + spacing=4, + orientation="h", + children=[ + self.status_container, + self.system_tray, + self.date_time, + ], + ), + ) + + invoke_repeater(1000, self.update_progress_bars) + + self.show_all() + + def update_progress_bars(self): + self.ram_progress_bar.value = psutil.virtual_memory().percent / 100 + self.cpu_progress_bar.value = psutil.cpu_percent() / 100 + return True + + +def main(): + bar = StatusBar() + app = Application("bar", bar) + app.set_stylesheet_from_file(get_relative_path("bar.css")) + + app.run() + + +if __name__ == "__main__": + main() diff --git a/bar/generated/__init__.py b/bar/generated/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bar/generated/river_control_unstable_v1/__init__.py b/bar/generated/river_control_unstable_v1/__init__.py new file mode 100644 index 0000000..3801d2e --- /dev/null +++ b/bar/generated/river_control_unstable_v1/__init__.py @@ -0,0 +1,18 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright 2020 The River Developers +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from .zriver_command_callback_v1 import ZriverCommandCallbackV1 # noqa: F401 +from .zriver_control_v1 import ZriverControlV1 # noqa: F401 diff --git a/bar/generated/river_control_unstable_v1/zriver_command_callback_v1.py b/bar/generated/river_control_unstable_v1/zriver_command_callback_v1.py new file mode 100644 index 0000000..0670e6f --- /dev/null +++ b/bar/generated/river_control_unstable_v1/zriver_command_callback_v1.py @@ -0,0 +1,90 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright 2020 The River Developers +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + + +class ZriverCommandCallbackV1(Interface): + """Callback object + + This object is created by the run_command request. Exactly one of the + success or failure events will be sent. This object will be destroyed by + the compositor after one of the events is sent. + """ + + name = "zriver_command_callback_v1" + version = 1 + + +class ZriverCommandCallbackV1Proxy(Proxy[ZriverCommandCallbackV1]): + interface = ZriverCommandCallbackV1 + + +class ZriverCommandCallbackV1Resource(Resource): + interface = ZriverCommandCallbackV1 + + @ZriverCommandCallbackV1.event( + Argument(ArgumentType.String), + ) + def success(self, output: str) -> None: + """Command successful + + Sent when the command has been successfully received and executed by + the compositor. Some commands may produce output, in which case the + output argument will be a non-empty string. + + :param output: + the output of the command + :type output: + `ArgumentType.String` + """ + self._post_event(0, output) + + @ZriverCommandCallbackV1.event( + Argument(ArgumentType.String), + ) + def failure(self, failure_message: str) -> None: + """Command failed + + Sent when the command could not be carried out. This could be due to + sending a non-existent command, no command, not enough arguments, too + many arguments, invalid arguments, etc. + + :param failure_message: + a message explaining why failure occurred + :type failure_message: + `ArgumentType.String` + """ + self._post_event(1, failure_message) + + +class ZriverCommandCallbackV1Global(Global): + interface = ZriverCommandCallbackV1 + + +ZriverCommandCallbackV1._gen_c() +ZriverCommandCallbackV1.proxy_class = ZriverCommandCallbackV1Proxy +ZriverCommandCallbackV1.resource_class = ZriverCommandCallbackV1Resource +ZriverCommandCallbackV1.global_class = ZriverCommandCallbackV1Global diff --git a/bar/generated/river_control_unstable_v1/zriver_control_v1.py b/bar/generated/river_control_unstable_v1/zriver_control_v1.py new file mode 100644 index 0000000..01a68f5 --- /dev/null +++ b/bar/generated/river_control_unstable_v1/zriver_control_v1.py @@ -0,0 +1,111 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright 2020 The River Developers +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from ..wayland import WlSeat +from .zriver_command_callback_v1 import ZriverCommandCallbackV1 + + +class ZriverControlV1(Interface): + """Run compositor commands + + This interface allows clients to run compositor commands and receive a + success/failure response with output or a failure message respectively. + + Each command is built up in a series of add_argument requests and executed + with a run_command request. The first argument is the command to be run. + + A complete list of commands should be made available in the man page of the + compositor. + """ + + name = "zriver_control_v1" + version = 1 + + +class ZriverControlV1Proxy(Proxy[ZriverControlV1]): + interface = ZriverControlV1 + + @ZriverControlV1.request() + def destroy(self) -> None: + """Destroy the river_control object + + This request indicates that the client will not use the river_control + object any more. Objects that have been created through this instance + are not affected. + """ + self._marshal(0) + self._destroy() + + @ZriverControlV1.request( + Argument(ArgumentType.String), + ) + def add_argument(self, argument: str) -> None: + """Add an argument to the current command + + Arguments are stored by the server in the order they were sent until + the run_command request is made. + + :param argument: + the argument to add + :type argument: + `ArgumentType.String` + """ + self._marshal(1, argument) + + @ZriverControlV1.request( + Argument(ArgumentType.Object, interface=WlSeat), + Argument(ArgumentType.NewId, interface=ZriverCommandCallbackV1), + ) + def run_command(self, seat: WlSeat) -> Proxy[ZriverCommandCallbackV1]: + """Run the current command + + Execute the command built up using the add_argument request for the + given seat. + + :param seat: + :type seat: + :class:`~pywayland.protocol.wayland.WlSeat` + :returns: + :class:`~pywayland.protocol.river_control_unstable_v1.ZriverCommandCallbackV1` + -- callback object + """ + callback = self._marshal_constructor(2, ZriverCommandCallbackV1, seat) + return callback + + +class ZriverControlV1Resource(Resource): + interface = ZriverControlV1 + + +class ZriverControlV1Global(Global): + interface = ZriverControlV1 + + +ZriverControlV1._gen_c() +ZriverControlV1.proxy_class = ZriverControlV1Proxy +ZriverControlV1.resource_class = ZriverControlV1Resource +ZriverControlV1.global_class = ZriverControlV1Global diff --git a/bar/generated/river_status_unstable_v1/__init__.py b/bar/generated/river_status_unstable_v1/__init__.py new file mode 100644 index 0000000..51d6f86 --- /dev/null +++ b/bar/generated/river_status_unstable_v1/__init__.py @@ -0,0 +1,19 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright 2020 The River Developers +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from .zriver_output_status_v1 import ZriverOutputStatusV1 # noqa: F401 +from .zriver_seat_status_v1 import ZriverSeatStatusV1 # noqa: F401 +from .zriver_status_manager_v1 import ZriverStatusManagerV1 # noqa: F401 diff --git a/bar/generated/river_status_unstable_v1/zriver_output_status_v1.py b/bar/generated/river_status_unstable_v1/zriver_output_status_v1.py new file mode 100644 index 0000000..1ddb246 --- /dev/null +++ b/bar/generated/river_status_unstable_v1/zriver_output_status_v1.py @@ -0,0 +1,140 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright 2020 The River Developers +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + + +class ZriverOutputStatusV1(Interface): + """Track output tags and focus + + This interface allows clients to receive information about the current + windowing state of an output. + """ + + name = "zriver_output_status_v1" + version = 4 + + +class ZriverOutputStatusV1Proxy(Proxy[ZriverOutputStatusV1]): + interface = ZriverOutputStatusV1 + + @ZriverOutputStatusV1.request() + def destroy(self) -> None: + """Destroy the river_output_status object + + This request indicates that the client will not use the + river_output_status object any more. + """ + self._marshal(0) + self._destroy() + + +class ZriverOutputStatusV1Resource(Resource): + interface = ZriverOutputStatusV1 + + @ZriverOutputStatusV1.event( + Argument(ArgumentType.Uint), + ) + def focused_tags(self, tags: int) -> None: + """Focused tags of the output + + Sent once binding the interface and again whenever the tag focus of the + output changes. + + :param tags: + 32-bit bitfield + :type tags: + `ArgumentType.Uint` + """ + self._post_event(0, tags) + + @ZriverOutputStatusV1.event( + Argument(ArgumentType.Array), + ) + def view_tags(self, tags: list) -> None: + """Tag state of an output's views + + Sent once on binding the interface and again whenever the tag state of + the output changes. + + :param tags: + array of 32-bit bitfields + :type tags: + `ArgumentType.Array` + """ + self._post_event(1, tags) + + @ZriverOutputStatusV1.event( + Argument(ArgumentType.Uint), + version=2, + ) + def urgent_tags(self, tags: int) -> None: + """Tags of the output with an urgent view + + Sent once on binding the interface and again whenever the set of tags + with at least one urgent view changes. + + :param tags: + 32-bit bitfield + :type tags: + `ArgumentType.Uint` + """ + self._post_event(2, tags) + + @ZriverOutputStatusV1.event( + Argument(ArgumentType.String), + version=4, + ) + def layout_name(self, name: str) -> None: + """Name of the layout + + Sent once on binding the interface should a layout name exist and again + whenever the name changes. + + :param name: + layout name + :type name: + `ArgumentType.String` + """ + self._post_event(3, name) + + @ZriverOutputStatusV1.event(version=4) + def layout_name_clear(self) -> None: + """Name of the layout + + Sent when the current layout name has been removed without a new one + being set, for example when the active layout generator disconnects. + """ + self._post_event(4) + + +class ZriverOutputStatusV1Global(Global): + interface = ZriverOutputStatusV1 + + +ZriverOutputStatusV1._gen_c() +ZriverOutputStatusV1.proxy_class = ZriverOutputStatusV1Proxy +ZriverOutputStatusV1.resource_class = ZriverOutputStatusV1Resource +ZriverOutputStatusV1.global_class = ZriverOutputStatusV1Global diff --git a/bar/generated/river_status_unstable_v1/zriver_seat_status_v1.py b/bar/generated/river_status_unstable_v1/zriver_seat_status_v1.py new file mode 100644 index 0000000..aef513a --- /dev/null +++ b/bar/generated/river_status_unstable_v1/zriver_seat_status_v1.py @@ -0,0 +1,131 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright 2020 The River Developers +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from ..wayland import WlOutput + + +class ZriverSeatStatusV1(Interface): + """Track seat focus + + This interface allows clients to receive information about the current + focus of a seat. Note that (un)focused_output events will only be sent if + the client has bound the relevant + :class:`~pywayland.protocol.wayland.WlOutput` globals. + """ + + name = "zriver_seat_status_v1" + version = 3 + + +class ZriverSeatStatusV1Proxy(Proxy[ZriverSeatStatusV1]): + interface = ZriverSeatStatusV1 + + @ZriverSeatStatusV1.request() + def destroy(self) -> None: + """Destroy the river_seat_status object + + This request indicates that the client will not use the + river_seat_status object any more. + """ + self._marshal(0) + self._destroy() + + +class ZriverSeatStatusV1Resource(Resource): + interface = ZriverSeatStatusV1 + + @ZriverSeatStatusV1.event( + Argument(ArgumentType.Object, interface=WlOutput), + ) + def focused_output(self, output: WlOutput) -> None: + """The seat focused an output + + Sent on binding the interface and again whenever an output gains focus. + + :param output: + :type output: + :class:`~pywayland.protocol.wayland.WlOutput` + """ + self._post_event(0, output) + + @ZriverSeatStatusV1.event( + Argument(ArgumentType.Object, interface=WlOutput), + ) + def unfocused_output(self, output: WlOutput) -> None: + """The seat unfocused an output + + Sent whenever an output loses focus. + + :param output: + :type output: + :class:`~pywayland.protocol.wayland.WlOutput` + """ + self._post_event(1, output) + + @ZriverSeatStatusV1.event( + Argument(ArgumentType.String), + ) + def focused_view(self, title: str) -> None: + """Information on the focused view + + Sent once on binding the interface and again whenever the focused view + or a property thereof changes. The title may be an empty string if no + view is focused or the focused view did not set a title. + + :param title: + title of the focused view + :type title: + `ArgumentType.String` + """ + self._post_event(2, title) + + @ZriverSeatStatusV1.event( + Argument(ArgumentType.String), + version=3, + ) + def mode(self, name: str) -> None: + """The active mode changed + + Sent once on binding the interface and again whenever a new mode is + entered (e.g. with riverctl enter-mode foobar). + + :param name: + name of the mode + :type name: + `ArgumentType.String` + """ + self._post_event(3, name) + + +class ZriverSeatStatusV1Global(Global): + interface = ZriverSeatStatusV1 + + +ZriverSeatStatusV1._gen_c() +ZriverSeatStatusV1.proxy_class = ZriverSeatStatusV1Proxy +ZriverSeatStatusV1.resource_class = ZriverSeatStatusV1Resource +ZriverSeatStatusV1.global_class = ZriverSeatStatusV1Global diff --git a/bar/generated/river_status_unstable_v1/zriver_status_manager_v1.py b/bar/generated/river_status_unstable_v1/zriver_status_manager_v1.py new file mode 100644 index 0000000..d18e8e7 --- /dev/null +++ b/bar/generated/river_status_unstable_v1/zriver_status_manager_v1.py @@ -0,0 +1,109 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright 2020 The River Developers +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from ..wayland import WlOutput +from ..wayland import WlSeat +from .zriver_output_status_v1 import ZriverOutputStatusV1 +from .zriver_seat_status_v1 import ZriverSeatStatusV1 + + +class ZriverStatusManagerV1(Interface): + """Manage river status objects + + A global factory for objects that receive status information specific to + river. It could be used to implement, for example, a status bar. + """ + + name = "zriver_status_manager_v1" + version = 4 + + +class ZriverStatusManagerV1Proxy(Proxy[ZriverStatusManagerV1]): + interface = ZriverStatusManagerV1 + + @ZriverStatusManagerV1.request() + def destroy(self) -> None: + """Destroy the river_status_manager object + + This request indicates that the client will not use the + river_status_manager object any more. Objects that have been created + through this instance are not affected. + """ + self._marshal(0) + self._destroy() + + @ZriverStatusManagerV1.request( + Argument(ArgumentType.NewId, interface=ZriverOutputStatusV1), + Argument(ArgumentType.Object, interface=WlOutput), + ) + def get_river_output_status(self, output: WlOutput) -> Proxy[ZriverOutputStatusV1]: + """Create an output status object + + This creates a new river_output_status object for the given + :class:`~pywayland.protocol.wayland.WlOutput`. + + :param output: + :type output: + :class:`~pywayland.protocol.wayland.WlOutput` + :returns: + :class:`~pywayland.protocol.river_status_unstable_v1.ZriverOutputStatusV1` + """ + id = self._marshal_constructor(1, ZriverOutputStatusV1, output) + return id + + @ZriverStatusManagerV1.request( + Argument(ArgumentType.NewId, interface=ZriverSeatStatusV1), + Argument(ArgumentType.Object, interface=WlSeat), + ) + def get_river_seat_status(self, seat: WlSeat) -> Proxy[ZriverSeatStatusV1]: + """Create a seat status object + + This creates a new river_seat_status object for the given + :class:`~pywayland.protocol.wayland.WlSeat`. + + :param seat: + :type seat: + :class:`~pywayland.protocol.wayland.WlSeat` + :returns: + :class:`~pywayland.protocol.river_status_unstable_v1.ZriverSeatStatusV1` + """ + id = self._marshal_constructor(2, ZriverSeatStatusV1, seat) + return id + + +class ZriverStatusManagerV1Resource(Resource): + interface = ZriverStatusManagerV1 + + +class ZriverStatusManagerV1Global(Global): + interface = ZriverStatusManagerV1 + + +ZriverStatusManagerV1._gen_c() +ZriverStatusManagerV1.proxy_class = ZriverStatusManagerV1Proxy +ZriverStatusManagerV1.resource_class = ZriverStatusManagerV1Resource +ZriverStatusManagerV1.global_class = ZriverStatusManagerV1Global diff --git a/bar/generated/wayland/__init__.py b/bar/generated/wayland/__init__.py new file mode 100644 index 0000000..cdd251d --- /dev/null +++ b/bar/generated/wayland/__init__.py @@ -0,0 +1,49 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from .wl_buffer import WlBuffer # noqa: F401 +from .wl_callback import WlCallback # noqa: F401 +from .wl_compositor import WlCompositor # noqa: F401 +from .wl_data_device import WlDataDevice # noqa: F401 +from .wl_data_device_manager import WlDataDeviceManager # noqa: F401 +from .wl_data_offer import WlDataOffer # noqa: F401 +from .wl_data_source import WlDataSource # noqa: F401 +from .wl_display import WlDisplay # noqa: F401 +from .wl_keyboard import WlKeyboard # noqa: F401 +from .wl_output import WlOutput # noqa: F401 +from .wl_pointer import WlPointer # noqa: F401 +from .wl_region import WlRegion # noqa: F401 +from .wl_registry import WlRegistry # noqa: F401 +from .wl_seat import WlSeat # noqa: F401 +from .wl_shell import WlShell # noqa: F401 +from .wl_shell_surface import WlShellSurface # noqa: F401 +from .wl_shm import WlShm # noqa: F401 +from .wl_shm_pool import WlShmPool # noqa: F401 +from .wl_subcompositor import WlSubcompositor # noqa: F401 +from .wl_subsurface import WlSubsurface # noqa: F401 +from .wl_surface import WlSurface # noqa: F401 +from .wl_touch import WlTouch # noqa: F401 diff --git a/bar/generated/wayland/wl_buffer.py b/bar/generated/wayland/wl_buffer.py new file mode 100644 index 0000000..e6801f8 --- /dev/null +++ b/bar/generated/wayland/wl_buffer.py @@ -0,0 +1,107 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import Global, Interface, Proxy, Resource + + +class WlBuffer(Interface): + """Content for a :class:`~pywayland.protocol.wayland.WlSurface` + + A buffer provides the content for a + :class:`~pywayland.protocol.wayland.WlSurface`. Buffers are created through + factory interfaces such as :class:`~pywayland.protocol.wayland.WlShm`, + wp_linux_buffer_params (from the linux-dmabuf protocol extension) or + similar. It has a width and a height and can be attached to a + :class:`~pywayland.protocol.wayland.WlSurface`, but the mechanism by which + a client provides and updates the contents is defined by the buffer factory + interface. + + If the buffer uses a format that has an alpha channel, the alpha channel is + assumed to be premultiplied in the color channels unless otherwise + specified. + + Note, because :class:`WlBuffer` objects are created from multiple + independent factory interfaces, the :class:`WlBuffer` interface is frozen + at version 1. + """ + + name = "wl_buffer" + version = 1 + + +class WlBufferProxy(Proxy[WlBuffer]): + interface = WlBuffer + + @WlBuffer.request() + def destroy(self) -> None: + """Destroy a buffer + + Destroy a buffer. If and how you need to release the backing storage is + defined by the buffer factory interface. + + For possible side-effects to a surface, see :func:`WlSurface.attach() + `. + """ + self._marshal(0) + self._destroy() + + +class WlBufferResource(Resource): + interface = WlBuffer + + @WlBuffer.event() + def release(self) -> None: + """Compositor releases buffer + + Sent when this :class:`WlBuffer` is no longer used by the compositor. + The client is now free to reuse or destroy this buffer and its backing + storage. + + If a client receives a release event before the frame callback + requested in the same :func:`WlSurface.commit() + ` that attaches this + :class:`WlBuffer` to a surface, then the client is immediately free to + reuse the buffer and its backing storage, and does not need a second + buffer for the next surface content update. Typically this is possible, + when the compositor maintains a copy of the + :class:`~pywayland.protocol.wayland.WlSurface` contents, e.g. as a GL + texture. This is an important optimization for GL(ES) compositors with + :class:`~pywayland.protocol.wayland.WlShm` clients. + """ + self._post_event(0) + + +class WlBufferGlobal(Global): + interface = WlBuffer + + +WlBuffer._gen_c() +WlBuffer.proxy_class = WlBufferProxy +WlBuffer.resource_class = WlBufferResource +WlBuffer.global_class = WlBufferGlobal diff --git a/bar/generated/wayland/wl_callback.py b/bar/generated/wayland/wl_callback.py new file mode 100644 index 0000000..33e9dec --- /dev/null +++ b/bar/generated/wayland/wl_callback.py @@ -0,0 +1,85 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + + +class WlCallback(Interface): + """Callback object + + Clients can handle the 'done' event to get notified when the related + request is done. + + Note, because :class:`WlCallback` objects are created from multiple + independent factory interfaces, the :class:`WlCallback` interface is frozen + at version 1. + """ + + name = "wl_callback" + version = 1 + + +class WlCallbackProxy(Proxy[WlCallback]): + interface = WlCallback + + +class WlCallbackResource(Resource): + interface = WlCallback + + @WlCallback.event( + Argument(ArgumentType.Uint), + ) + def done(self, callback_data: int) -> None: + """Done event + + Notify the client when the related request is done. + + :param callback_data: + request-specific data for the callback + :type callback_data: + `ArgumentType.Uint` + """ + self._post_event(0, callback_data) + + +class WlCallbackGlobal(Global): + interface = WlCallback + + +WlCallback._gen_c() +WlCallback.proxy_class = WlCallbackProxy +WlCallback.resource_class = WlCallbackResource +WlCallback.global_class = WlCallbackGlobal diff --git a/bar/generated/wayland/wl_compositor.py b/bar/generated/wayland/wl_compositor.py new file mode 100644 index 0000000..61de75b --- /dev/null +++ b/bar/generated/wayland/wl_compositor.py @@ -0,0 +1,98 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_region import WlRegion +from .wl_surface import WlSurface + + +class WlCompositor(Interface): + """The compositor singleton + + A compositor. This object is a singleton global. The compositor is in + charge of combining the contents of multiple surfaces into one displayable + output. + """ + + name = "wl_compositor" + version = 6 + + +class WlCompositorProxy(Proxy[WlCompositor]): + interface = WlCompositor + + @WlCompositor.request( + Argument(ArgumentType.NewId, interface=WlSurface), + ) + def create_surface(self) -> Proxy[WlSurface]: + """Create new surface + + Ask the compositor to create a new surface. + + :returns: + :class:`~pywayland.protocol.wayland.WlSurface` -- the new surface + """ + id = self._marshal_constructor(0, WlSurface) + return id + + @WlCompositor.request( + Argument(ArgumentType.NewId, interface=WlRegion), + ) + def create_region(self) -> Proxy[WlRegion]: + """Create new region + + Ask the compositor to create a new region. + + :returns: + :class:`~pywayland.protocol.wayland.WlRegion` -- the new region + """ + id = self._marshal_constructor(1, WlRegion) + return id + + +class WlCompositorResource(Resource): + interface = WlCompositor + + +class WlCompositorGlobal(Global): + interface = WlCompositor + + +WlCompositor._gen_c() +WlCompositor.proxy_class = WlCompositorProxy +WlCompositor.resource_class = WlCompositorResource +WlCompositor.global_class = WlCompositorGlobal diff --git a/bar/generated/wayland/wl_data_device.py b/bar/generated/wayland/wl_data_device.py new file mode 100644 index 0000000..22b1740 --- /dev/null +++ b/bar/generated/wayland/wl_data_device.py @@ -0,0 +1,311 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_data_offer import WlDataOffer +from .wl_data_source import WlDataSource +from .wl_surface import WlSurface + + +class WlDataDevice(Interface): + """Data transfer device + + There is one :class:`WlDataDevice` per seat which can be obtained from the + global :class:`~pywayland.protocol.wayland.WlDataDeviceManager` singleton. + + A :class:`WlDataDevice` provides access to inter-client data transfer + mechanisms such as copy-and-paste and drag-and-drop. + """ + + name = "wl_data_device" + version = 3 + + class error(enum.IntEnum): + role = 0 + + +class WlDataDeviceProxy(Proxy[WlDataDevice]): + interface = WlDataDevice + + @WlDataDevice.request( + Argument(ArgumentType.Object, interface=WlDataSource, nullable=True), + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Object, interface=WlSurface, nullable=True), + Argument(ArgumentType.Uint), + ) + def start_drag(self, source: WlDataSource | None, origin: WlSurface, icon: WlSurface | None, serial: int) -> None: + """Start drag-and-drop operation + + This request asks the compositor to start a drag-and-drop operation on + behalf of the client. + + The source argument is the data source that provides the data for the + eventual data transfer. If source is NULL, enter, leave and motion + events are sent only to the client that initiated the drag and the + client is expected to handle the data passing internally. If source is + destroyed, the drag-and-drop session will be cancelled. + + The origin surface is the surface where the drag originates and the + client must have an active implicit grab that matches the serial. + + The icon surface is an optional (can be NULL) surface that provides an + icon to be moved around with the cursor. Initially, the top-left + corner of the icon surface is placed at the cursor hotspot, but + subsequent :func:`WlSurface.attach() + ` request can move the + relative position. Attach requests must be confirmed with + :func:`WlSurface.commit() + ` as usual. The icon + surface is given the role of a drag-and-drop icon. If the icon surface + already has another role, it raises a protocol error. + + The input region is ignored for wl_surfaces with the role of a drag- + and-drop icon. + + :param source: + data source for the eventual transfer + :type source: + :class:`~pywayland.protocol.wayland.WlDataSource` or `None` + :param origin: + surface where the drag originates + :type origin: + :class:`~pywayland.protocol.wayland.WlSurface` + :param icon: + drag-and-drop icon surface + :type icon: + :class:`~pywayland.protocol.wayland.WlSurface` or `None` + :param serial: + serial number of the implicit grab on the origin + :type serial: + `ArgumentType.Uint` + """ + self._marshal(0, source, origin, icon, serial) + + @WlDataDevice.request( + Argument(ArgumentType.Object, interface=WlDataSource, nullable=True), + Argument(ArgumentType.Uint), + ) + def set_selection(self, source: WlDataSource | None, serial: int) -> None: + """Copy data to the selection + + This request asks the compositor to set the selection to the data from + the source on behalf of the client. + + To unset the selection, set the source to NULL. + + :param source: + data source for the selection + :type source: + :class:`~pywayland.protocol.wayland.WlDataSource` or `None` + :param serial: + serial number of the event that triggered this request + :type serial: + `ArgumentType.Uint` + """ + self._marshal(1, source, serial) + + @WlDataDevice.request(version=2) + def release(self) -> None: + """Destroy data device + + This request destroys the data device. + """ + self._marshal(2) + self._destroy() + + +class WlDataDeviceResource(Resource): + interface = WlDataDevice + + @WlDataDevice.event( + Argument(ArgumentType.NewId, interface=WlDataOffer), + ) + def data_offer(self, id: WlDataOffer) -> None: + """Introduce a new :class:`~pywayland.protocol.wayland.WlDataOffer` + + The data_offer event introduces a new + :class:`~pywayland.protocol.wayland.WlDataOffer` object, which will + subsequently be used in either the data_device.enter event (for drag- + and-drop) or the data_device.selection event (for selections). + Immediately following the data_device.data_offer event, the new + data_offer object will send out data_offer.offer events to describe the + mime types it offers. + + :param id: + the new data_offer object + :type id: + :class:`~pywayland.protocol.wayland.WlDataOffer` + """ + self._post_event(0, id) + + @WlDataDevice.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Object, interface=WlDataOffer, nullable=True), + ) + def enter(self, serial: int, surface: WlSurface, x: float, y: float, id: WlDataOffer | None) -> None: + """Initiate drag-and-drop session + + This event is sent when an active drag-and-drop pointer enters a + surface owned by the client. The position of the pointer at enter time + is provided by the x and y arguments, in surface-local coordinates. + + :param serial: + serial number of the enter event + :type serial: + `ArgumentType.Uint` + :param surface: + client surface entered + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Fixed` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Fixed` + :param id: + source data_offer object + :type id: + :class:`~pywayland.protocol.wayland.WlDataOffer` or `None` + """ + self._post_event(1, serial, surface, x, y, id) + + @WlDataDevice.event() + def leave(self) -> None: + """End drag-and-drop session + + This event is sent when the drag-and-drop pointer leaves the surface + and the session ends. The client must destroy the + :class:`~pywayland.protocol.wayland.WlDataOffer` introduced at enter + time at this point. + """ + self._post_event(2) + + @WlDataDevice.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Fixed), + ) + def motion(self, time: int, x: float, y: float) -> None: + """Drag-and-drop session motion + + This event is sent when the drag-and-drop pointer moves within the + currently focused surface. The new position of the pointer is provided + by the x and y arguments, in surface-local coordinates. + + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Fixed` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Fixed` + """ + self._post_event(3, time, x, y) + + @WlDataDevice.event() + def drop(self) -> None: + """End drag-and-drop session successfully + + The event is sent when a drag-and-drop operation is ended because the + implicit grab is removed. + + The drag-and-drop destination is expected to honor the last action + received through :func:`WlDataOffer.action() + `, if the resulting + action is "copy" or "move", the destination can still perform + :func:`WlDataOffer.receive() + ` requests, and is + expected to end all transfers with a :func:`WlDataOffer.finish() + ` request. + + If the resulting action is "ask", the action will not be considered + final. The drag-and-drop destination is expected to perform one last + :func:`WlDataOffer.set_actions() + ` request, or + :func:`WlDataOffer.destroy() + ` in order to cancel + the operation. + """ + self._post_event(4) + + @WlDataDevice.event( + Argument(ArgumentType.Object, interface=WlDataOffer, nullable=True), + ) + def selection(self, id: WlDataOffer | None) -> None: + """Advertise new selection + + The selection event is sent out to notify the client of a new + :class:`~pywayland.protocol.wayland.WlDataOffer` for the selection for + this device. The data_device.data_offer and the data_offer.offer + events are sent out immediately before this event to introduce the data + offer object. The selection event is sent to a client immediately + before receiving keyboard focus and when a new selection is set while + the client has keyboard focus. The data_offer is valid until a new + data_offer or NULL is received or until the client loses keyboard + focus. Switching surface with keyboard focus within the same client + doesn't mean a new selection will be sent. The client must destroy the + previous selection data_offer, if any, upon receiving this event. + + :param id: + selection data_offer object + :type id: + :class:`~pywayland.protocol.wayland.WlDataOffer` or `None` + """ + self._post_event(5, id) + + +class WlDataDeviceGlobal(Global): + interface = WlDataDevice + + +WlDataDevice._gen_c() +WlDataDevice.proxy_class = WlDataDeviceProxy +WlDataDevice.resource_class = WlDataDeviceResource +WlDataDevice.global_class = WlDataDeviceGlobal diff --git a/bar/generated/wayland/wl_data_device_manager.py b/bar/generated/wayland/wl_data_device_manager.py new file mode 100644 index 0000000..b6644f9 --- /dev/null +++ b/bar/generated/wayland/wl_data_device_manager.py @@ -0,0 +1,126 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_data_device import WlDataDevice +from .wl_data_source import WlDataSource +from .wl_seat import WlSeat + + +class WlDataDeviceManager(Interface): + """Data transfer interface + + The :class:`WlDataDeviceManager` is a singleton global object that provides + access to inter-client data transfer mechanisms such as copy-and-paste and + drag-and-drop. These mechanisms are tied to a + :class:`~pywayland.protocol.wayland.WlSeat` and this interface lets a + client get a :class:`~pywayland.protocol.wayland.WlDataDevice` + corresponding to a :class:`~pywayland.protocol.wayland.WlSeat`. + + Depending on the version bound, the objects created from the bound + :class:`WlDataDeviceManager` object will have different requirements for + functioning properly. See :func:`WlDataSource.set_actions() + `, + :func:`WlDataOffer.accept() + ` and + :func:`WlDataOffer.finish() + ` for details. + """ + + name = "wl_data_device_manager" + version = 3 + + class dnd_action(enum.IntFlag): + none = 0 + copy = 1 + move = 2 + ask = 4 + + +class WlDataDeviceManagerProxy(Proxy[WlDataDeviceManager]): + interface = WlDataDeviceManager + + @WlDataDeviceManager.request( + Argument(ArgumentType.NewId, interface=WlDataSource), + ) + def create_data_source(self) -> Proxy[WlDataSource]: + """Create a new data source + + Create a new data source. + + :returns: + :class:`~pywayland.protocol.wayland.WlDataSource` -- data source to + create + """ + id = self._marshal_constructor(0, WlDataSource) + return id + + @WlDataDeviceManager.request( + Argument(ArgumentType.NewId, interface=WlDataDevice), + Argument(ArgumentType.Object, interface=WlSeat), + ) + def get_data_device(self, seat: WlSeat) -> Proxy[WlDataDevice]: + """Create a new data device + + Create a new data device for a given seat. + + :param seat: + seat associated with the data device + :type seat: + :class:`~pywayland.protocol.wayland.WlSeat` + :returns: + :class:`~pywayland.protocol.wayland.WlDataDevice` -- data device to + create + """ + id = self._marshal_constructor(1, WlDataDevice, seat) + return id + + +class WlDataDeviceManagerResource(Resource): + interface = WlDataDeviceManager + + +class WlDataDeviceManagerGlobal(Global): + interface = WlDataDeviceManager + + +WlDataDeviceManager._gen_c() +WlDataDeviceManager.proxy_class = WlDataDeviceManagerProxy +WlDataDeviceManager.resource_class = WlDataDeviceManagerResource +WlDataDeviceManager.global_class = WlDataDeviceManagerGlobal diff --git a/bar/generated/wayland/wl_data_offer.py b/bar/generated/wayland/wl_data_offer.py new file mode 100644 index 0000000..4f35bac --- /dev/null +++ b/bar/generated/wayland/wl_data_offer.py @@ -0,0 +1,325 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + + +class WlDataOffer(Interface): + """Offer to transfer data + + A :class:`WlDataOffer` represents a piece of data offered for transfer by + another client (the source client). It is used by the copy-and-paste and + drag-and-drop mechanisms. The offer describes the different mime types + that the data can be converted to and provides the mechanism for + transferring the data directly from the source client. + """ + + name = "wl_data_offer" + version = 3 + + class error(enum.IntEnum): + invalid_finish = 0 + invalid_action_mask = 1 + invalid_action = 2 + invalid_offer = 3 + + +class WlDataOfferProxy(Proxy[WlDataOffer]): + interface = WlDataOffer + + @WlDataOffer.request( + Argument(ArgumentType.Uint), + Argument(ArgumentType.String, nullable=True), + ) + def accept(self, serial: int, mime_type: str | None) -> None: + """Accept one of the offered mime types + + Indicate that the client can accept the given mime type, or NULL for + not accepted. + + For objects of version 2 or older, this request is used by the client + to give feedback whether the client can receive the given mime type, or + NULL if none is accepted; the feedback does not determine whether the + drag-and-drop operation succeeds or not. + + For objects of version 3 or newer, this request determines the final + result of the drag-and-drop operation. If the end result is that no + mime types were accepted, the drag-and-drop operation will be cancelled + and the corresponding drag source will receive + :func:`WlDataSource.cancelled() + `. Clients may still + use this event in conjunction with :func:`WlDataSource.action() + ` for feedback. + + :param serial: + serial number of the accept request + :type serial: + `ArgumentType.Uint` + :param mime_type: + mime type accepted by the client + :type mime_type: + `ArgumentType.String` or `None` + """ + self._marshal(0, serial, mime_type) + + @WlDataOffer.request( + Argument(ArgumentType.String), + Argument(ArgumentType.FileDescriptor), + ) + def receive(self, mime_type: str, fd: int) -> None: + """Request that the data is transferred + + To transfer the offered data, the client issues this request and + indicates the mime type it wants to receive. The transfer happens + through the passed file descriptor (typically created with the pipe + system call). The source client writes the data in the mime type + representation requested and then closes the file descriptor. + + The receiving client reads from the read end of the pipe until EOF and + then closes its end, at which point the transfer is complete. + + This request may happen multiple times for different mime types, both + before and after :func:`WlDataDevice.drop() + `. Drag-and-drop + destination clients may preemptively fetch data or examine it more + closely to determine acceptance. + + :param mime_type: + mime type desired by receiver + :type mime_type: + `ArgumentType.String` + :param fd: + file descriptor for data transfer + :type fd: + `ArgumentType.FileDescriptor` + """ + self._marshal(1, mime_type, fd) + + @WlDataOffer.request() + def destroy(self) -> None: + """Destroy data offer + + Destroy the data offer. + """ + self._marshal(2) + self._destroy() + + @WlDataOffer.request(version=3) + def finish(self) -> None: + """The offer will no longer be used + + Notifies the compositor that the drag destination successfully finished + the drag-and-drop operation. + + Upon receiving this request, the compositor will emit + :func:`WlDataSource.dnd_finished() + ` on the drag + source client. + + It is a client error to perform other requests than + :func:`WlDataOffer.destroy()` after this one. It is also an error to + perform this request after a NULL mime type has been set in + :func:`WlDataOffer.accept()` or no action was received through + :func:`WlDataOffer.action()`. + + If :func:`WlDataOffer.finish()` request is received for a non drag and + drop operation, the invalid_finish protocol error is raised. + """ + self._marshal(3) + + @WlDataOffer.request( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + version=3, + ) + def set_actions(self, dnd_actions: int, preferred_action: int) -> None: + """Set the available/preferred drag-and-drop actions + + Sets the actions that the destination side client supports for this + operation. This request may trigger the emission of + :func:`WlDataSource.action() + ` and + :func:`WlDataOffer.action()` events if the compositor needs to change + the selected action. + + This request can be called multiple times throughout the drag-and-drop + operation, typically in response to :func:`WlDataDevice.enter() + ` or + :func:`WlDataDevice.motion() + ` events. + + This request determines the final result of the drag-and-drop + operation. If the end result is that no action is accepted, the drag + source will receive :func:`WlDataSource.cancelled() + `. + + The dnd_actions argument must contain only values expressed in the + :func:`WlDataDeviceManager.dnd_actions() + ` enum, and + the preferred_action argument must only contain one of those values + set, otherwise it will result in a protocol error. + + While managing an "ask" action, the destination drag-and-drop client + may perform further :func:`WlDataOffer.receive()` requests, and is + expected to perform one last :func:`WlDataOffer.set_actions()` request + with a preferred action other than "ask" (and optionally + :func:`WlDataOffer.accept()`) before requesting + :func:`WlDataOffer.finish()`, in order to convey the action selected by + the user. If the preferred action is not in the + :func:`WlDataOffer.source_actions()` mask, an error will be raised. + + If the "ask" action is dismissed (e.g. user cancellation), the client + is expected to perform :func:`WlDataOffer.destroy()` right away. + + This request can only be made on drag-and-drop offers, a protocol error + will be raised otherwise. + + :param dnd_actions: + actions supported by the destination client + :type dnd_actions: + `ArgumentType.Uint` + :param preferred_action: + action preferred by the destination client + :type preferred_action: + `ArgumentType.Uint` + """ + self._marshal(4, dnd_actions, preferred_action) + + +class WlDataOfferResource(Resource): + interface = WlDataOffer + + @WlDataOffer.event( + Argument(ArgumentType.String), + ) + def offer(self, mime_type: str) -> None: + """Advertise offered mime type + + Sent immediately after creating the :class:`WlDataOffer` object. One + event per offered mime type. + + :param mime_type: + offered mime type + :type mime_type: + `ArgumentType.String` + """ + self._post_event(0, mime_type) + + @WlDataOffer.event( + Argument(ArgumentType.Uint), + version=3, + ) + def source_actions(self, source_actions: int) -> None: + """Notify the source-side available actions + + This event indicates the actions offered by the data source. It will be + sent immediately after creating the :class:`WlDataOffer` object, or + anytime the source side changes its offered actions through + :func:`WlDataSource.set_actions() + `. + + :param source_actions: + actions offered by the data source + :type source_actions: + `ArgumentType.Uint` + """ + self._post_event(1, source_actions) + + @WlDataOffer.event( + Argument(ArgumentType.Uint), + version=3, + ) + def action(self, dnd_action: int) -> None: + """Notify the selected action + + This event indicates the action selected by the compositor after + matching the source/destination side actions. Only one action (or none) + will be offered here. + + This event can be emitted multiple times during the drag-and-drop + operation in response to destination side action changes through + :func:`WlDataOffer.set_actions()`. + + This event will no longer be emitted after :func:`WlDataDevice.drop() + ` happened on the drag- + and-drop destination, the client must honor the last action received, + or the last preferred one set through :func:`WlDataOffer.set_actions()` + when handling an "ask" action. + + Compositors may also change the selected action on the fly, mainly in + response to keyboard modifier changes during the drag-and-drop + operation. + + The most recent action received is always the valid one. Prior to + receiving :func:`WlDataDevice.drop() + `, the chosen action may + change (e.g. due to keyboard modifiers being pressed). At the time of + receiving :func:`WlDataDevice.drop() + ` the drag-and-drop + destination must honor the last action received. + + Action changes may still happen after :func:`WlDataDevice.drop() + `, especially on "ask" + actions, where the drag-and-drop destination may choose another action + afterwards. Action changes happening at this stage are always the + result of inter-client negotiation, the compositor shall no longer be + able to induce a different action. + + Upon "ask" actions, it is expected that the drag-and-drop destination + may potentially choose a different action and/or mime type, based on + :func:`WlDataOffer.source_actions()` and finally chosen by the user + (e.g. popping up a menu with the available options). The final + :func:`WlDataOffer.set_actions()` and :func:`WlDataOffer.accept()` + requests must happen before the call to :func:`WlDataOffer.finish()`. + + :param dnd_action: + action selected by the compositor + :type dnd_action: + `ArgumentType.Uint` + """ + self._post_event(2, dnd_action) + + +class WlDataOfferGlobal(Global): + interface = WlDataOffer + + +WlDataOffer._gen_c() +WlDataOffer.proxy_class = WlDataOfferProxy +WlDataOffer.resource_class = WlDataOfferResource +WlDataOffer.global_class = WlDataOfferGlobal diff --git a/bar/generated/wayland/wl_data_source.py b/bar/generated/wayland/wl_data_source.py new file mode 100644 index 0000000..780d417 --- /dev/null +++ b/bar/generated/wayland/wl_data_source.py @@ -0,0 +1,273 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + + +class WlDataSource(Interface): + """Offer to transfer data + + The :class:`WlDataSource` object is the source side of a + :class:`~pywayland.protocol.wayland.WlDataOffer`. It is created by the + source client in a data transfer and provides a way to describe the offered + data and a way to respond to requests to transfer the data. + """ + + name = "wl_data_source" + version = 3 + + class error(enum.IntEnum): + invalid_action_mask = 0 + invalid_source = 1 + + +class WlDataSourceProxy(Proxy[WlDataSource]): + interface = WlDataSource + + @WlDataSource.request( + Argument(ArgumentType.String), + ) + def offer(self, mime_type: str) -> None: + """Add an offered mime type + + This request adds a mime type to the set of mime types advertised to + targets. Can be called several times to offer multiple types. + + :param mime_type: + mime type offered by the data source + :type mime_type: + `ArgumentType.String` + """ + self._marshal(0, mime_type) + + @WlDataSource.request() + def destroy(self) -> None: + """Destroy the data source + + Destroy the data source. + """ + self._marshal(1) + self._destroy() + + @WlDataSource.request( + Argument(ArgumentType.Uint), + version=3, + ) + def set_actions(self, dnd_actions: int) -> None: + """Set the available drag-and-drop actions + + Sets the actions that the source side client supports for this + operation. This request may trigger :func:`WlDataSource.action()` and + :func:`WlDataOffer.action() + ` events if the + compositor needs to change the selected action. + + The dnd_actions argument must contain only values expressed in the + :func:`WlDataDeviceManager.dnd_actions() + ` enum, + otherwise it will result in a protocol error. + + This request must be made once only, and can only be made on sources + used in drag-and-drop, so it must be performed before + :func:`WlDataDevice.start_drag() + `. Attempting to + use the source other than for drag-and-drop will raise a protocol + error. + + :param dnd_actions: + actions supported by the data source + :type dnd_actions: + `ArgumentType.Uint` + """ + self._marshal(2, dnd_actions) + + +class WlDataSourceResource(Resource): + interface = WlDataSource + + @WlDataSource.event( + Argument(ArgumentType.String, nullable=True), + ) + def target(self, mime_type: str | None) -> None: + """A target accepts an offered mime type + + Sent when a target accepts pointer_focus or motion events. If a target + does not accept any of the offered types, type is NULL. + + Used for feedback during drag-and-drop. + + :param mime_type: + mime type accepted by the target + :type mime_type: + `ArgumentType.String` or `None` + """ + self._post_event(0, mime_type) + + @WlDataSource.event( + Argument(ArgumentType.String), + Argument(ArgumentType.FileDescriptor), + ) + def send(self, mime_type: str, fd: int) -> None: + """Send the data + + Request for data from the client. Send the data as the specified mime + type over the passed file descriptor, then close it. + + :param mime_type: + mime type for the data + :type mime_type: + `ArgumentType.String` + :param fd: + file descriptor for the data + :type fd: + `ArgumentType.FileDescriptor` + """ + self._post_event(1, mime_type, fd) + + @WlDataSource.event() + def cancelled(self) -> None: + """Selection was cancelled + + This data source is no longer valid. There are several reasons why this + could happen: + + - The data source has been replaced by another data source. + + - The drag-and-drop operation was performed, but the drop destination + did not accept any of the mime types offered through + :func:`WlDataSource.target()`. + + - The drag-and-drop operation was performed, but the drop destination + did not select any of the actions present in the mask offered through + :func:`WlDataSource.action()`. + + - The drag-and-drop operation was performed but didn't happen over a + surface. + + - The compositor cancelled the drag-and-drop operation (e.g. compositor + dependent timeouts to avoid stale drag-and-drop transfers). + + The client should clean up and destroy this data source. + + For objects of version 2 or older, :func:`WlDataSource.cancelled()` + will only be emitted if the data source was replaced by another data + source. + """ + self._post_event(2) + + @WlDataSource.event(version=3) + def dnd_drop_performed(self) -> None: + """The drag-and-drop operation physically finished + + The user performed the drop action. This event does not indicate + acceptance, :func:`WlDataSource.cancelled()` may still be emitted + afterwards if the drop destination does not accept any mime type. + + However, this event might however not be received if the compositor + cancelled the drag-and-drop operation before this event could happen. + + Note that the data_source may still be used in the future and should + not be destroyed here. + """ + self._post_event(3) + + @WlDataSource.event(version=3) + def dnd_finished(self) -> None: + """The drag-and-drop operation concluded + + The drop destination finished interoperating with this data source, so + the client is now free to destroy this data source and free all + associated data. + + If the action used to perform the operation was "move", the source can + now delete the transferred data. + """ + self._post_event(4) + + @WlDataSource.event( + Argument(ArgumentType.Uint), + version=3, + ) + def action(self, dnd_action: int) -> None: + """Notify the selected action + + This event indicates the action selected by the compositor after + matching the source/destination side actions. Only one action (or none) + will be offered here. + + This event can be emitted multiple times during the drag-and-drop + operation, mainly in response to destination side changes through + :func:`WlDataOffer.set_actions() + `, and as the data + device enters/leaves surfaces. + + It is only possible to receive this event after + :func:`WlDataSource.dnd_drop_performed()` if the drag-and-drop + operation ended in an "ask" action, in which case the final + :func:`WlDataSource.action()` event will happen immediately before + :func:`WlDataSource.dnd_finished()`. + + Compositors may also change the selected action on the fly, mainly in + response to keyboard modifier changes during the drag-and-drop + operation. + + The most recent action received is always the valid one. The chosen + action may change alongside negotiation (e.g. an "ask" action can turn + into a "move" operation), so the effects of the final action must + always be applied in :func:`WlDataOffer.dnd_finished() + `. + + Clients can trigger cursor surface changes from this point, so they + reflect the current action. + + :param dnd_action: + action selected by the compositor + :type dnd_action: + `ArgumentType.Uint` + """ + self._post_event(5, dnd_action) + + +class WlDataSourceGlobal(Global): + interface = WlDataSource + + +WlDataSource._gen_c() +WlDataSource.proxy_class = WlDataSourceProxy +WlDataSource.resource_class = WlDataSourceResource +WlDataSource.global_class = WlDataSourceGlobal diff --git a/bar/generated/wayland/wl_display.py b/bar/generated/wayland/wl_display.py new file mode 100644 index 0000000..636b5b6 --- /dev/null +++ b/bar/generated/wayland/wl_display.py @@ -0,0 +1,175 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from typing import Any + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_callback import WlCallback +from .wl_registry import WlRegistry + + +class WlDisplay(Interface): + """Core global object + + The core global object. This is a special singleton object. It is used + for internal Wayland protocol features. + """ + + name = "wl_display" + version = 1 + + class error(enum.IntEnum): + invalid_object = 0 + invalid_method = 1 + no_memory = 2 + implementation = 3 + + +class WlDisplayProxy(Proxy[WlDisplay]): + interface = WlDisplay + + @WlDisplay.request( + Argument(ArgumentType.NewId, interface=WlCallback), + ) + def sync(self) -> Proxy[WlCallback]: + """Asynchronous roundtrip + + The sync request asks the server to emit the 'done' event on the + returned :class:`~pywayland.protocol.wayland.WlCallback` object. Since + requests are handled in-order and events are delivered in-order, this + can be used as a barrier to ensure all previous requests and the + resulting events have been handled. + + The object returned by this request will be destroyed by the compositor + after the callback is fired and as such the client must not attempt to + use it after that point. + + The callback_data passed in the callback is the event serial. + + :returns: + :class:`~pywayland.protocol.wayland.WlCallback` -- callback object + for the sync request + """ + callback = self._marshal_constructor(0, WlCallback) + return callback + + @WlDisplay.request( + Argument(ArgumentType.NewId, interface=WlRegistry), + ) + def get_registry(self) -> Proxy[WlRegistry]: + """Get global registry object + + This request creates a registry object that allows the client to list + and bind the global objects available from the compositor. + + It should be noted that the server side resources consumed in response + to a get_registry request can only be released when the client + disconnects, not when the client side proxy is destroyed. Therefore, + clients should invoke get_registry as infrequently as possible to avoid + wasting memory. + + :returns: + :class:`~pywayland.protocol.wayland.WlRegistry` -- global registry + object + """ + registry = self._marshal_constructor(1, WlRegistry) + return registry + + +class WlDisplayResource(Resource): + interface = WlDisplay + + @WlDisplay.event( + Argument(ArgumentType.Object), + Argument(ArgumentType.Uint), + Argument(ArgumentType.String), + ) + def error(self, object_id: Any, code: int, message: str) -> None: + """Fatal error event + + The error event is sent out when a fatal (non-recoverable) error has + occurred. The object_id argument is the object where the error + occurred, most often in response to a request to that object. The code + identifies the error and is defined by the object interface. As such, + each interface defines its own set of error codes. The message is a + brief description of the error, for (debugging) convenience. + + :param object_id: + object where the error occurred + :type object_id: + `ArgumentType.Object` + :param code: + error code + :type code: + `ArgumentType.Uint` + :param message: + error description + :type message: + `ArgumentType.String` + """ + self._post_event(0, object_id, code, message) + + @WlDisplay.event( + Argument(ArgumentType.Uint), + ) + def delete_id(self, id: int) -> None: + """Acknowledge object id deletion + + This event is used internally by the object ID management logic. When a + client deletes an object that it had created, the server will send this + event to acknowledge that it has seen the delete request. When the + client receives this event, it will know that it can safely reuse the + object ID. + + :param id: + deleted object ID + :type id: + `ArgumentType.Uint` + """ + self._post_event(1, id) + + +class WlDisplayGlobal(Global): + interface = WlDisplay + + +WlDisplay._gen_c() +WlDisplay.proxy_class = WlDisplayProxy +WlDisplay.resource_class = WlDisplayResource +WlDisplay.global_class = WlDisplayGlobal diff --git a/bar/generated/wayland/wl_keyboard.py b/bar/generated/wayland/wl_keyboard.py new file mode 100644 index 0000000..5488b05 --- /dev/null +++ b/bar/generated/wayland/wl_keyboard.py @@ -0,0 +1,276 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_surface import WlSurface + + +class WlKeyboard(Interface): + """Keyboard input device + + The :class:`WlKeyboard` interface represents one or more keyboards + associated with a seat. + """ + + name = "wl_keyboard" + version = 9 + + class keymap_format(enum.IntEnum): + no_keymap = 0 + xkb_v1 = 1 + + class key_state(enum.IntEnum): + released = 0 + pressed = 1 + + +class WlKeyboardProxy(Proxy[WlKeyboard]): + interface = WlKeyboard + + @WlKeyboard.request(version=3) + def release(self) -> None: + """Release the keyboard object + """ + self._marshal(0) + self._destroy() + + +class WlKeyboardResource(Resource): + interface = WlKeyboard + + @WlKeyboard.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.FileDescriptor), + Argument(ArgumentType.Uint), + ) + def keymap(self, format: int, fd: int, size: int) -> None: + """Keyboard mapping + + This event provides a file descriptor to the client which can be + memory-mapped in read-only mode to provide a keyboard mapping + description. + + From version 7 onwards, the fd must be mapped with MAP_PRIVATE by the + recipient, as MAP_SHARED may fail. + + :param format: + keymap format + :type format: + `ArgumentType.Uint` + :param fd: + keymap file descriptor + :type fd: + `ArgumentType.FileDescriptor` + :param size: + keymap size, in bytes + :type size: + `ArgumentType.Uint` + """ + self._post_event(0, format, fd, size) + + @WlKeyboard.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Array), + ) + def enter(self, serial: int, surface: WlSurface, keys: list) -> None: + """Enter event + + Notification that this seat's keyboard focus is on a certain surface. + + The compositor must send the :func:`WlKeyboard.modifiers()` event after + this event. + + :param serial: + serial number of the enter event + :type serial: + `ArgumentType.Uint` + :param surface: + surface gaining keyboard focus + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + :param keys: + the currently pressed keys + :type keys: + `ArgumentType.Array` + """ + self._post_event(1, serial, surface, keys) + + @WlKeyboard.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface), + ) + def leave(self, serial: int, surface: WlSurface) -> None: + """Leave event + + Notification that this seat's keyboard focus is no longer on a certain + surface. + + The leave notification is sent before the enter notification for the + new focus. + + After this event client must assume that all keys, including modifiers, + are lifted and also it must stop key repeating if there's some going + on. + + :param serial: + serial number of the leave event + :type serial: + `ArgumentType.Uint` + :param surface: + surface that lost keyboard focus + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + """ + self._post_event(2, serial, surface) + + @WlKeyboard.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + ) + def key(self, serial: int, time: int, key: int, state: int) -> None: + """Key event + + A key was pressed or released. The time argument is a timestamp with + millisecond granularity, with an undefined base. + + The key is a platform-specific key code that can be interpreted by + feeding it to the keyboard mapping (see the keymap event). + + If this event produces a change in modifiers, then the resulting + :func:`WlKeyboard.modifiers()` event must be sent after this event. + + :param serial: + serial number of the key event + :type serial: + `ArgumentType.Uint` + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param key: + key that produced the event + :type key: + `ArgumentType.Uint` + :param state: + physical state of the key + :type state: + `ArgumentType.Uint` + """ + self._post_event(3, serial, time, key, state) + + @WlKeyboard.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + ) + def modifiers(self, serial: int, mods_depressed: int, mods_latched: int, mods_locked: int, group: int) -> None: + """Modifier and group state + + Notifies clients that the modifier and/or group state has changed, and + it should update its local state. + + :param serial: + serial number of the modifiers event + :type serial: + `ArgumentType.Uint` + :param mods_depressed: + depressed modifiers + :type mods_depressed: + `ArgumentType.Uint` + :param mods_latched: + latched modifiers + :type mods_latched: + `ArgumentType.Uint` + :param mods_locked: + locked modifiers + :type mods_locked: + `ArgumentType.Uint` + :param group: + keyboard layout + :type group: + `ArgumentType.Uint` + """ + self._post_event(4, serial, mods_depressed, mods_latched, mods_locked, group) + + @WlKeyboard.event( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + version=4, + ) + def repeat_info(self, rate: int, delay: int) -> None: + """Repeat rate and delay + + Informs the client about the keyboard's repeat rate and delay. + + This event is sent as soon as the :class:`WlKeyboard` object has been + created, and is guaranteed to be received by the client before any key + press event. + + Negative values for either rate or delay are illegal. A rate of zero + will disable any repeating (regardless of the value of delay). + + This event can be sent later on as well with a new value if necessary, + so clients should continue listening for the event past the creation of + :class:`WlKeyboard`. + + :param rate: + the rate of repeating keys in characters per second + :type rate: + `ArgumentType.Int` + :param delay: + delay in milliseconds since key down until repeating starts + :type delay: + `ArgumentType.Int` + """ + self._post_event(5, rate, delay) + + +class WlKeyboardGlobal(Global): + interface = WlKeyboard + + +WlKeyboard._gen_c() +WlKeyboard.proxy_class = WlKeyboardProxy +WlKeyboard.resource_class = WlKeyboardResource +WlKeyboard.global_class = WlKeyboardGlobal diff --git a/bar/generated/wayland/wl_output.py b/bar/generated/wayland/wl_output.py new file mode 100644 index 0000000..9650e53 --- /dev/null +++ b/bar/generated/wayland/wl_output.py @@ -0,0 +1,349 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + + +class WlOutput(Interface): + """Compositor output region + + An output describes part of the compositor geometry. The compositor works + in the 'compositor coordinate system' and an output corresponds to a + rectangular area in that space that is actually visible. This typically + corresponds to a monitor that displays part of the compositor space. This + object is published as global during start up, or when a monitor is + hotplugged. + """ + + name = "wl_output" + version = 4 + + class subpixel(enum.IntEnum): + unknown = 0 + none = 1 + horizontal_rgb = 2 + horizontal_bgr = 3 + vertical_rgb = 4 + vertical_bgr = 5 + + class transform(enum.IntEnum): + normal = 0 + transform_90 = 1 + transform_180 = 2 + transform_270 = 3 + flipped = 4 + flipped_90 = 5 + flipped_180 = 6 + flipped_270 = 7 + + class mode(enum.IntFlag): + current = 0x1 + preferred = 0x2 + + +class WlOutputProxy(Proxy[WlOutput]): + interface = WlOutput + + @WlOutput.request(version=3) + def release(self) -> None: + """Release the output object + + Using this request a client can tell the server that it is not going to + use the output object anymore. + """ + self._marshal(0) + self._destroy() + + +class WlOutputResource(Resource): + interface = WlOutput + + @WlOutput.event( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.String), + Argument(ArgumentType.String), + Argument(ArgumentType.Int), + ) + def geometry(self, x: int, y: int, physical_width: int, physical_height: int, subpixel: int, make: str, model: str, transform: int) -> None: + """Properties of the output + + The geometry event describes geometric properties of the output. The + event is sent when binding to the output object and whenever any of the + properties change. + + The physical size can be set to zero if it doesn't make sense for this + output (e.g. for projectors or virtual outputs). + + The geometry event will be followed by a done event (starting from + version 2). + + Note: :class:`WlOutput` only advertises partial information about the + output position and identification. Some compositors, for instance + those not implementing a desktop-style output layout or those exposing + virtual outputs, might fake this information. Instead of using x and y, + clients should use xdg_output.logical_position. Instead of using make + and model, clients should use name and description. + + :param x: + x position within the global compositor space + :type x: + `ArgumentType.Int` + :param y: + y position within the global compositor space + :type y: + `ArgumentType.Int` + :param physical_width: + width in millimeters of the output + :type physical_width: + `ArgumentType.Int` + :param physical_height: + height in millimeters of the output + :type physical_height: + `ArgumentType.Int` + :param subpixel: + subpixel orientation of the output + :type subpixel: + `ArgumentType.Int` + :param make: + textual description of the manufacturer + :type make: + `ArgumentType.String` + :param model: + textual description of the model + :type model: + `ArgumentType.String` + :param transform: + transform that maps framebuffer to output + :type transform: + `ArgumentType.Int` + """ + self._post_event(0, x, y, physical_width, physical_height, subpixel, make, model, transform) + + @WlOutput.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def mode(self, flags: int, width: int, height: int, refresh: int) -> None: + """Advertise available modes for the output + + The mode event describes an available mode for the output. + + The event is sent when binding to the output object and there will + always be one mode, the current mode. The event is sent again if an + output changes mode, for the mode that is now current. In other words, + the current mode is always the last mode that was received with the + current flag set. + + Non-current modes are deprecated. A compositor can decide to only + advertise the current mode and never send other modes. Clients should + not rely on non-current modes. + + The size of a mode is given in physical hardware units of the output + device. This is not necessarily the same as the output size in the + global compositor space. For instance, the output may be scaled, as + described in :func:`WlOutput.scale()`, or transformed, as described in + :func:`WlOutput.transform()`. Clients willing to retrieve the output + size in the global compositor space should use xdg_output.logical_size + instead. + + The vertical refresh rate can be set to zero if it doesn't make sense + for this output (e.g. for virtual outputs). + + The mode event will be followed by a done event (starting from version + 2). + + Clients should not use the refresh rate to schedule frames. Instead, + they should use the :func:`WlSurface.frame() + ` event or the + presentation-time protocol. + + Note: this information is not always meaningful for all outputs. Some + compositors, such as those exposing virtual outputs, might fake the + refresh rate or the size. + + :param flags: + bitfield of mode flags + :type flags: + `ArgumentType.Uint` + :param width: + width of the mode in hardware units + :type width: + `ArgumentType.Int` + :param height: + height of the mode in hardware units + :type height: + `ArgumentType.Int` + :param refresh: + vertical refresh rate in mHz + :type refresh: + `ArgumentType.Int` + """ + self._post_event(1, flags, width, height, refresh) + + @WlOutput.event(version=2) + def done(self) -> None: + """Sent all information about output + + This event is sent after all other properties have been sent after + binding to the output object and after any other property changes done + after that. This allows changes to the output properties to be seen as + atomic, even if they happen via multiple events. + """ + self._post_event(2) + + @WlOutput.event( + Argument(ArgumentType.Int), + version=2, + ) + def scale(self, factor: int) -> None: + """Output scaling properties + + This event contains scaling geometry information that is not in the + geometry event. It may be sent after binding the output object or if + the output scale changes later. If it is not sent, the client should + assume a scale of 1. + + A scale larger than 1 means that the compositor will automatically + scale surface buffers by this amount when rendering. This is used for + very high resolution displays where applications rendering at the + native resolution would be too small to be legible. + + It is intended that scaling aware clients track the current output of a + surface, and if it is on a scaled output it should use + :func:`WlSurface.set_buffer_scale() + ` with the scale + of the output. That way the compositor can avoid scaling the surface, + and the client can supply a higher detail image. + + The scale event will be followed by a done event. + + :param factor: + scaling factor of output + :type factor: + `ArgumentType.Int` + """ + self._post_event(3, factor) + + @WlOutput.event( + Argument(ArgumentType.String), + version=4, + ) + def name(self, name: str) -> None: + """Name of this output + + Many compositors will assign user-friendly names to their outputs, show + them to the user, allow the user to refer to an output, etc. The client + may wish to know this name as well to offer the user similar behaviors. + + The name is a UTF-8 string with no convention defined for its contents. + Each name is unique among all :class:`WlOutput` globals. The name is + only guaranteed to be unique for the compositor instance. + + The same output name is used for all clients for a given + :class:`WlOutput` global. Thus, the name can be shared across processes + to refer to a specific :class:`WlOutput` global. + + The name is not guaranteed to be persistent across sessions, thus + cannot be used to reliably identify an output in e.g. configuration + files. + + Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do + not assume that the name is a reflection of an underlying DRM + connector, X11 connection, etc. + + The name event is sent after binding the output object. This event is + only sent once per output object, and the name does not change over the + lifetime of the :class:`WlOutput` global. + + Compositors may re-use the same output name if the :class:`WlOutput` + global is destroyed and re-created later. Compositors should avoid re- + using the same name if possible. + + The name event will be followed by a done event. + + :param name: + output name + :type name: + `ArgumentType.String` + """ + self._post_event(4, name) + + @WlOutput.event( + Argument(ArgumentType.String), + version=4, + ) + def description(self, description: str) -> None: + """Human-readable description of this output + + Many compositors can produce human-readable descriptions of their + outputs. The client may wish to know this description as well, e.g. for + output selection purposes. + + The description is a UTF-8 string with no convention defined for its + contents. The description is not guaranteed to be unique among all + :class:`WlOutput` globals. Examples might include 'Foocorp 11" Display' + or 'Virtual X11 output via :1'. + + The description event is sent after binding the output object and + whenever the description changes. The description is optional, and may + not be sent at all. + + The description event will be followed by a done event. + + :param description: + output description + :type description: + `ArgumentType.String` + """ + self._post_event(5, description) + + +class WlOutputGlobal(Global): + interface = WlOutput + + +WlOutput._gen_c() +WlOutput.proxy_class = WlOutputProxy +WlOutput.resource_class = WlOutputResource +WlOutput.global_class = WlOutputGlobal diff --git a/bar/generated/wayland/wl_pointer.py b/bar/generated/wayland/wl_pointer.py new file mode 100644 index 0000000..c8f0108 --- /dev/null +++ b/bar/generated/wayland/wl_pointer.py @@ -0,0 +1,592 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_surface import WlSurface + + +class WlPointer(Interface): + """Pointer input device + + The :class:`WlPointer` interface represents one or more input devices, such + as mice, which control the pointer location and pointer_focus of a seat. + + The :class:`WlPointer` interface generates motion, enter and leave events + for the surfaces that the pointer is located over, and button and axis + events for button presses, button releases and scrolling. + """ + + name = "wl_pointer" + version = 9 + + class error(enum.IntEnum): + role = 0 + + class button_state(enum.IntEnum): + released = 0 + pressed = 1 + + class axis(enum.IntEnum): + vertical_scroll = 0 + horizontal_scroll = 1 + + class axis_source(enum.IntEnum): + wheel = 0 + finger = 1 + continuous = 2 + wheel_tilt = 3 + + class axis_relative_direction(enum.IntEnum): + identical = 0 + inverted = 1 + + +class WlPointerProxy(Proxy[WlPointer]): + interface = WlPointer + + @WlPointer.request( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface, nullable=True), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def set_cursor(self, serial: int, surface: WlSurface | None, hotspot_x: int, hotspot_y: int) -> None: + """Set the pointer surface + + Set the pointer surface, i.e., the surface that contains the pointer + image (cursor). This request gives the surface the role of a cursor. If + the surface already has another role, it raises a protocol error. + + The cursor actually changes only if the pointer focus for this device + is one of the requesting client's surfaces or the surface parameter is + the current pointer surface. If there was a previous surface set with + this request it is replaced. If surface is NULL, the pointer image is + hidden. + + The parameters hotspot_x and hotspot_y define the position of the + pointer surface relative to the pointer location. Its top-left corner + is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the + coordinates of the pointer location, in surface-local coordinates. + + On surface.attach requests to the pointer surface, hotspot_x and + hotspot_y are decremented by the x and y parameters passed to the + request. Attach must be confirmed by :func:`WlSurface.commit() + ` as usual. + + The hotspot can also be updated by passing the currently set pointer + surface to this request with new values for hotspot_x and hotspot_y. + + The input region is ignored for wl_surfaces with the role of a cursor. + When the use as a cursor ends, the + :class:`~pywayland.protocol.wayland.WlSurface` is unmapped. + + The serial parameter must match the latest :func:`WlPointer.enter()` + serial number sent to the client. Otherwise the request will be + ignored. + + :param serial: + serial number of the enter event + :type serial: + `ArgumentType.Uint` + :param surface: + pointer surface + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` or `None` + :param hotspot_x: + surface-local x coordinate + :type hotspot_x: + `ArgumentType.Int` + :param hotspot_y: + surface-local y coordinate + :type hotspot_y: + `ArgumentType.Int` + """ + self._marshal(0, serial, surface, hotspot_x, hotspot_y) + + @WlPointer.request(version=3) + def release(self) -> None: + """Release the pointer object + + Using this request a client can tell the server that it is not going to + use the pointer object anymore. + + This request destroys the pointer proxy object, so clients must not + call wl_pointer_destroy() after using this request. + """ + self._marshal(1) + self._destroy() + + +class WlPointerResource(Resource): + interface = WlPointer + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Fixed), + ) + def enter(self, serial: int, surface: WlSurface, surface_x: float, surface_y: float) -> None: + """Enter event + + Notification that this seat's pointer is focused on a certain surface. + + When a seat's focus enters a surface, the pointer image is undefined + and a client should respond to this event by setting an appropriate + pointer image with the set_cursor request. + + :param serial: + serial number of the enter event + :type serial: + `ArgumentType.Uint` + :param surface: + surface entered by the pointer + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + :param surface_x: + surface-local x coordinate + :type surface_x: + `ArgumentType.Fixed` + :param surface_y: + surface-local y coordinate + :type surface_y: + `ArgumentType.Fixed` + """ + self._post_event(0, serial, surface, surface_x, surface_y) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface), + ) + def leave(self, serial: int, surface: WlSurface) -> None: + """Leave event + + Notification that this seat's pointer is no longer focused on a certain + surface. + + The leave notification is sent before the enter notification for the + new focus. + + :param serial: + serial number of the leave event + :type serial: + `ArgumentType.Uint` + :param surface: + surface left by the pointer + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + """ + self._post_event(1, serial, surface) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Fixed), + ) + def motion(self, time: int, surface_x: float, surface_y: float) -> None: + """Pointer motion event + + Notification of pointer location change. The arguments surface_x and + surface_y are the location relative to the focused surface. + + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param surface_x: + surface-local x coordinate + :type surface_x: + `ArgumentType.Fixed` + :param surface_y: + surface-local y coordinate + :type surface_y: + `ArgumentType.Fixed` + """ + self._post_event(2, time, surface_x, surface_y) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + ) + def button(self, serial: int, time: int, button: int, state: int) -> None: + """Pointer button event + + Mouse button click and release notifications. + + The location of the click is given by the last motion or enter event. + The time argument is a timestamp with millisecond granularity, with an + undefined base. + + The button is a button code as defined in the Linux kernel's + linux/input-event-codes.h header file, e.g. BTN_LEFT. + + Any 16-bit button code value is reserved for future additions to the + kernel's event code list. All other button codes above 0xFFFF are + currently undefined but may be used in future versions of this + protocol. + + :param serial: + serial number of the button event + :type serial: + `ArgumentType.Uint` + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param button: + button that produced the event + :type button: + `ArgumentType.Uint` + :param state: + physical state of the button + :type state: + `ArgumentType.Uint` + """ + self._post_event(3, serial, time, button, state) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Fixed), + ) + def axis(self, time: int, axis: int, value: float) -> None: + """Axis event + + Scroll and other axis notifications. + + For scroll events (vertical and horizontal scroll axes), the value + parameter is the length of a vector along the specified axis in a + coordinate space identical to those of motion events, representing a + relative movement along the specified axis. + + For devices that support movements non-parallel to axes multiple axis + events will be emitted. + + When applicable, for example for touch pads, the server can choose to + emit scroll events where the motion vector is equivalent to a motion + event vector. + + When applicable, a client can transform its content relative to the + scroll distance. + + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param axis: + axis type + :type axis: + `ArgumentType.Uint` + :param value: + length of vector in surface-local coordinate space + :type value: + `ArgumentType.Fixed` + """ + self._post_event(4, time, axis, value) + + @WlPointer.event(version=5) + def frame(self) -> None: + """End of a pointer event sequence + + Indicates the end of a set of events that logically belong together. A + client is expected to accumulate the data in all events within the + frame before proceeding. + + All :class:`WlPointer` events before a :func:`WlPointer.frame()` event + belong logically together. For example, in a diagonal scroll motion the + compositor will send an optional :func:`WlPointer.axis_source()` event, + two :func:`WlPointer.axis()` events (horizontal and vertical) and + finally a :func:`WlPointer.frame()` event. The client may use this + information to calculate a diagonal vector for scrolling. + + When multiple :func:`WlPointer.axis()` events occur within the same + frame, the motion vector is the combined motion of all events. When a + :func:`WlPointer.axis()` and a :func:`WlPointer.axis_stop()` event + occur within the same frame, this indicates that axis movement in one + axis has stopped but continues in the other axis. When multiple + :func:`WlPointer.axis_stop()` events occur within the same frame, this + indicates that these axes stopped in the same instance. + + A :func:`WlPointer.frame()` event is sent for every logical event + group, even if the group only contains a single :class:`WlPointer` + event. Specifically, a client may get a sequence: motion, frame, + button, frame, axis, frame, axis_stop, frame. + + The :func:`WlPointer.enter()` and :func:`WlPointer.leave()` events are + logical events generated by the compositor and not the hardware. These + events are also grouped by a :func:`WlPointer.frame()`. When a pointer + moves from one surface to another, a compositor should group the + :func:`WlPointer.leave()` event within the same + :func:`WlPointer.frame()`. However, a client must not rely on + :func:`WlPointer.leave()` and :func:`WlPointer.enter()` being in the + same :func:`WlPointer.frame()`. Compositor-specific policies may + require the :func:`WlPointer.leave()` and :func:`WlPointer.enter()` + event being split across multiple :func:`WlPointer.frame()` groups. + """ + self._post_event(5) + + @WlPointer.event( + Argument(ArgumentType.Uint), + version=5, + ) + def axis_source(self, axis_source: int) -> None: + """Axis source event + + Source information for scroll and other axes. + + This event does not occur on its own. It is sent before a + :func:`WlPointer.frame()` event and carries the source information for + all events within that frame. + + The source specifies how this event was generated. If the source is + :func:`WlPointer.axis_source()`.finger, a :func:`WlPointer.axis_stop()` + event will be sent when the user lifts the finger off the device. + + If the source is :func:`WlPointer.axis_source()`.wheel, + :func:`WlPointer.axis_source()`.wheel_tilt or + :func:`WlPointer.axis_source()`.continuous, a + :func:`WlPointer.axis_stop()` event may or may not be sent. Whether a + compositor sends an axis_stop event for these sources is hardware- + specific and implementation-dependent; clients must not rely on + receiving an axis_stop event for these scroll sources and should treat + scroll sequences from these scroll sources as unterminated by default. + + This event is optional. If the source is unknown for a particular axis + event sequence, no event is sent. Only one + :func:`WlPointer.axis_source()` event is permitted per frame. + + The order of :func:`WlPointer.axis_discrete()` and + :func:`WlPointer.axis_source()` is not guaranteed. + + :param axis_source: + source of the axis event + :type axis_source: + `ArgumentType.Uint` + """ + self._post_event(6, axis_source) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + version=5, + ) + def axis_stop(self, time: int, axis: int) -> None: + """Axis stop event + + Stop notification for scroll and other axes. + + For some :func:`WlPointer.axis_source()` types, a + :func:`WlPointer.axis_stop()` event is sent to notify a client that the + axis sequence has terminated. This enables the client to implement + kinetic scrolling. See the :func:`WlPointer.axis_source()` + documentation for information on when this event may be generated. + + Any :func:`WlPointer.axis()` events with the same axis_source after + this event should be considered as the start of a new axis motion. + + The timestamp is to be interpreted identical to the timestamp in the + :func:`WlPointer.axis()` event. The timestamp value may be the same as + a preceding :func:`WlPointer.axis()` event. + + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param axis: + the axis stopped with this event + :type axis: + `ArgumentType.Uint` + """ + self._post_event(7, time, axis) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Int), + version=5, + ) + def axis_discrete(self, axis: int, discrete: int) -> None: + """Axis click event + + Discrete step information for scroll and other axes. + + This event carries the axis value of the :func:`WlPointer.axis()` event + in discrete steps (e.g. mouse wheel clicks). + + This event is deprecated with :class:`WlPointer` version 8 - this event + is not sent to clients supporting version 8 or later. + + This event does not occur on its own, it is coupled with a + :func:`WlPointer.axis()` event that represents this axis value on a + continuous scale. The protocol guarantees that each axis_discrete event + is always followed by exactly one axis event with the same axis number + within the same :func:`WlPointer.frame()`. Note that the protocol + allows for other events to occur between the axis_discrete and its + coupled axis event, including other axis_discrete or axis events. A + :func:`WlPointer.frame()` must not contain more than one axis_discrete + event per axis type. + + This event is optional; continuous scrolling devices like two-finger + scrolling on touchpads do not have discrete steps and do not generate + this event. + + The discrete value carries the directional information. e.g. a value of + -2 is two steps towards the negative direction of this axis. + + The axis number is identical to the axis number in the associated axis + event. + + The order of :func:`WlPointer.axis_discrete()` and + :func:`WlPointer.axis_source()` is not guaranteed. + + :param axis: + axis type + :type axis: + `ArgumentType.Uint` + :param discrete: + number of steps + :type discrete: + `ArgumentType.Int` + """ + self._post_event(8, axis, discrete) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Int), + version=8, + ) + def axis_value120(self, axis: int, value120: int) -> None: + """Axis high-resolution scroll event + + Discrete high-resolution scroll information. + + This event carries high-resolution wheel scroll information, with each + multiple of 120 representing one logical scroll step (a wheel detent). + For example, an axis_value120 of 30 is one quarter of a logical scroll + step in the positive direction, a value120 of -240 are two logical + scroll steps in the negative direction within the same hardware event. + Clients that rely on discrete scrolling should accumulate the value120 + to multiples of 120 before processing the event. + + The value120 must not be zero. + + This event replaces the :func:`WlPointer.axis_discrete()` event in + clients supporting :class:`WlPointer` version 8 or later. + + Where a :func:`WlPointer.axis_source()` event occurs in the same + :func:`WlPointer.frame()`, the axis source applies to this event. + + The order of :class:`WlPointer`.axis_value120 and + :func:`WlPointer.axis_source()` is not guaranteed. + + :param axis: + axis type + :type axis: + `ArgumentType.Uint` + :param value120: + scroll distance as fraction of 120 + :type value120: + `ArgumentType.Int` + """ + self._post_event(9, axis, value120) + + @WlPointer.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + version=9, + ) + def axis_relative_direction(self, axis: int, direction: int) -> None: + """Axis relative physical direction event + + Relative directional information of the entity causing the axis motion. + + For a :func:`WlPointer.axis()` event, the + :func:`WlPointer.axis_relative_direction()` event specifies the + movement direction of the entity causing the :func:`WlPointer.axis()` + event. For example: - if a user's fingers on a touchpad move down and + this causes a :func:`WlPointer.axis()` vertical_scroll down event, + the physical direction is 'identical' - if a user's fingers on a + touchpad move down and this causes a :func:`WlPointer.axis()` + vertical_scroll up scroll up event ('natural scrolling'), the + physical direction is 'inverted'. + + A client may use this information to adjust scroll motion of + components. Specifically, enabling natural scrolling causes the content + to change direction compared to traditional scrolling. Some widgets + like volume control sliders should usually match the physical direction + regardless of whether natural scrolling is active. This event enables + clients to match the scroll direction of a widget to the physical + direction. + + This event does not occur on its own, it is coupled with a + :func:`WlPointer.axis()` event that represents this axis value. The + protocol guarantees that each axis_relative_direction event is always + followed by exactly one axis event with the same axis number within the + same :func:`WlPointer.frame()`. Note that the protocol allows for other + events to occur between the axis_relative_direction and its coupled + axis event. + + The axis number is identical to the axis number in the associated axis + event. + + The order of :func:`WlPointer.axis_relative_direction()`, + :func:`WlPointer.axis_discrete()` and :func:`WlPointer.axis_source()` + is not guaranteed. + + :param axis: + axis type + :type axis: + `ArgumentType.Uint` + :param direction: + physical direction relative to axis motion + :type direction: + `ArgumentType.Uint` + """ + self._post_event(10, axis, direction) + + +class WlPointerGlobal(Global): + interface = WlPointer + + +WlPointer._gen_c() +WlPointer.proxy_class = WlPointerProxy +WlPointer.resource_class = WlPointerResource +WlPointer.global_class = WlPointerGlobal diff --git a/bar/generated/wayland/wl_region.py b/bar/generated/wayland/wl_region.py new file mode 100644 index 0000000..efef5a2 --- /dev/null +++ b/bar/generated/wayland/wl_region.py @@ -0,0 +1,137 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + + +class WlRegion(Interface): + """Region interface + + A region object describes an area. + + Region objects are used to describe the opaque and input regions of a + surface. + """ + + name = "wl_region" + version = 1 + + +class WlRegionProxy(Proxy[WlRegion]): + interface = WlRegion + + @WlRegion.request() + def destroy(self) -> None: + """Destroy region + + Destroy the region. This will invalidate the object ID. + """ + self._marshal(0) + self._destroy() + + @WlRegion.request( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def add(self, x: int, y: int, width: int, height: int) -> None: + """Add rectangle to region + + Add the specified rectangle to the region. + + :param x: + region-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + region-local y coordinate + :type y: + `ArgumentType.Int` + :param width: + rectangle width + :type width: + `ArgumentType.Int` + :param height: + rectangle height + :type height: + `ArgumentType.Int` + """ + self._marshal(1, x, y, width, height) + + @WlRegion.request( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def subtract(self, x: int, y: int, width: int, height: int) -> None: + """Subtract rectangle from region + + Subtract the specified rectangle from the region. + + :param x: + region-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + region-local y coordinate + :type y: + `ArgumentType.Int` + :param width: + rectangle width + :type width: + `ArgumentType.Int` + :param height: + rectangle height + :type height: + `ArgumentType.Int` + """ + self._marshal(2, x, y, width, height) + + +class WlRegionResource(Resource): + interface = WlRegion + + +class WlRegionGlobal(Global): + interface = WlRegion + + +WlRegion._gen_c() +WlRegion.proxy_class = WlRegionProxy +WlRegion.resource_class = WlRegionResource +WlRegion.global_class = WlRegionGlobal diff --git a/bar/generated/wayland/wl_registry.py b/bar/generated/wayland/wl_registry.py new file mode 100644 index 0000000..54d1e45 --- /dev/null +++ b/bar/generated/wayland/wl_registry.py @@ -0,0 +1,167 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +from typing import TypeVar + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +T = TypeVar("T", bound=Interface) + + +class WlRegistry(Interface): + """Global registry object + + The singleton global registry object. The server has a number of global + objects that are available to all clients. These objects typically + represent an actual object in the server (for example, an input device) or + they are singleton objects that provide extension functionality. + + When a client creates a registry object, the registry object will emit a + global event for each global currently in the registry. Globals come and + go as a result of device or monitor hotplugs, reconfiguration or other + events, and the registry will send out global and global_remove events to + keep the client up to date with the changes. To mark the end of the + initial burst of events, the client can use the :func:`WlDisplay.sync() + ` request immediately after + calling :func:`WlDisplay.get_registry() + `. + + A client can bind to a global object by using the bind request. This + creates a client-side handle that lets the object emit events to the client + and lets the client invoke requests on the object. + """ + + name = "wl_registry" + version = 1 + + +class WlRegistryProxy(Proxy[WlRegistry]): + interface = WlRegistry + + @WlRegistry.request( + Argument(ArgumentType.Uint), + Argument(ArgumentType.NewId), + ) + def bind(self, name: int, interface: type[T], version: int) -> Proxy[T]: + """Bind an object to the display + + Binds a new, client-created object to the server using the specified + name as the identifier. + + :param name: + unique numeric name of the object + :type name: + `ArgumentType.Uint` + :param interface: + Interface name + :type interface: + `string` + :param version: + Interface version + :type version: + `int` + :returns: + :class:`pywayland.client.proxy.Proxy` of specified Interface -- + bounded object + """ + id = self._marshal_constructor(0, interface, name, interface.name, version) + return id + + +class WlRegistryResource(Resource): + interface = WlRegistry + + @WlRegistry.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.String), + Argument(ArgumentType.Uint), + ) + def global_(self, name: int, interface: str, version: int) -> None: + """Announce global object + + Notify the client of global objects. + + The event notifies the client that a global object with the given name + is now available, and it implements the given version of the given + interface. + + :param name: + numeric name of the global object + :type name: + `ArgumentType.Uint` + :param interface: + interface implemented by the object + :type interface: + `ArgumentType.String` + :param version: + interface version + :type version: + `ArgumentType.Uint` + """ + self._post_event(0, name, interface, version) + + @WlRegistry.event( + Argument(ArgumentType.Uint), + ) + def global_remove(self, name: int) -> None: + """Announce removal of global object + + Notify the client of removed global objects. + + This event notifies the client that the global identified by name is no + longer available. If the client bound to the global using the bind + request, the client should now destroy that object. + + The object remains valid and requests to the object will be ignored + until the client destroys it, to avoid races between the global going + away and a client sending a request to it. + + :param name: + numeric name of the global object + :type name: + `ArgumentType.Uint` + """ + self._post_event(1, name) + + +class WlRegistryGlobal(Global): + interface = WlRegistry + + +WlRegistry._gen_c() +WlRegistry.proxy_class = WlRegistryProxy +WlRegistry.resource_class = WlRegistryResource +WlRegistry.global_class = WlRegistryGlobal diff --git a/bar/generated/wayland/wl_seat.py b/bar/generated/wayland/wl_seat.py new file mode 100644 index 0000000..6f34457 --- /dev/null +++ b/bar/generated/wayland/wl_seat.py @@ -0,0 +1,232 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_keyboard import WlKeyboard +from .wl_pointer import WlPointer +from .wl_touch import WlTouch + + +class WlSeat(Interface): + """Group of input devices + + A seat is a group of keyboards, pointer and touch devices. This object is + published as a global during start up, or when such a device is hot + plugged. A seat typically has a pointer and maintains a keyboard focus and + a pointer focus. + """ + + name = "wl_seat" + version = 9 + + class capability(enum.IntFlag): + pointer = 1 + keyboard = 2 + touch = 4 + + class error(enum.IntEnum): + missing_capability = 0 + + +class WlSeatProxy(Proxy[WlSeat]): + interface = WlSeat + + @WlSeat.request( + Argument(ArgumentType.NewId, interface=WlPointer), + ) + def get_pointer(self) -> Proxy[WlPointer]: + """Return pointer object + + The ID provided will be initialized to the + :class:`~pywayland.protocol.wayland.WlPointer` interface for this seat. + + This request only takes effect if the seat has the pointer capability, + or has had the pointer capability in the past. It is a protocol + violation to issue this request on a seat that has never had the + pointer capability. The missing_capability error will be sent in this + case. + + :returns: + :class:`~pywayland.protocol.wayland.WlPointer` -- seat pointer + """ + id = self._marshal_constructor(0, WlPointer) + return id + + @WlSeat.request( + Argument(ArgumentType.NewId, interface=WlKeyboard), + ) + def get_keyboard(self) -> Proxy[WlKeyboard]: + """Return keyboard object + + The ID provided will be initialized to the + :class:`~pywayland.protocol.wayland.WlKeyboard` interface for this + seat. + + This request only takes effect if the seat has the keyboard capability, + or has had the keyboard capability in the past. It is a protocol + violation to issue this request on a seat that has never had the + keyboard capability. The missing_capability error will be sent in this + case. + + :returns: + :class:`~pywayland.protocol.wayland.WlKeyboard` -- seat keyboard + """ + id = self._marshal_constructor(1, WlKeyboard) + return id + + @WlSeat.request( + Argument(ArgumentType.NewId, interface=WlTouch), + ) + def get_touch(self) -> Proxy[WlTouch]: + """Return touch object + + The ID provided will be initialized to the + :class:`~pywayland.protocol.wayland.WlTouch` interface for this seat. + + This request only takes effect if the seat has the touch capability, or + has had the touch capability in the past. It is a protocol violation to + issue this request on a seat that has never had the touch capability. + The missing_capability error will be sent in this case. + + :returns: + :class:`~pywayland.protocol.wayland.WlTouch` -- seat touch + interface + """ + id = self._marshal_constructor(2, WlTouch) + return id + + @WlSeat.request(version=5) + def release(self) -> None: + """Release the seat object + + Using this request a client can tell the server that it is not going to + use the seat object anymore. + """ + self._marshal(3) + self._destroy() + + +class WlSeatResource(Resource): + interface = WlSeat + + @WlSeat.event( + Argument(ArgumentType.Uint), + ) + def capabilities(self, capabilities: int) -> None: + """Seat capabilities changed + + This is emitted whenever a seat gains or loses the pointer, keyboard or + touch capabilities. The argument is a capability enum containing the + complete set of capabilities this seat has. + + When the pointer capability is added, a client may create a + :class:`~pywayland.protocol.wayland.WlPointer` object using the + :func:`WlSeat.get_pointer()` request. This object will receive pointer + events until the capability is removed in the future. + + When the pointer capability is removed, a client should destroy the + :class:`~pywayland.protocol.wayland.WlPointer` objects associated with + the seat where the capability was removed, using the + :func:`WlPointer.release() + ` request. No further + pointer events will be received on these objects. + + In some compositors, if a seat regains the pointer capability and a + client has a previously obtained + :class:`~pywayland.protocol.wayland.WlPointer` object of version 4 or + less, that object may start sending pointer events again. This behavior + is considered a misinterpretation of the intended behavior and must not + be relied upon by the client. + :class:`~pywayland.protocol.wayland.WlPointer` objects of version 5 or + later must not send events if created before the most recent event + notifying the client of an added pointer capability. + + The above behavior also applies to + :class:`~pywayland.protocol.wayland.WlKeyboard` and + :class:`~pywayland.protocol.wayland.WlTouch` with the keyboard and + touch capabilities, respectively. + + :param capabilities: + capabilities of the seat + :type capabilities: + `ArgumentType.Uint` + """ + self._post_event(0, capabilities) + + @WlSeat.event( + Argument(ArgumentType.String), + version=2, + ) + def name(self, name: str) -> None: + """Unique identifier for this seat + + In a multi-seat configuration the seat name can be used by clients to + help identify which physical devices the seat represents. + + The seat name is a UTF-8 string with no convention defined for its + contents. Each name is unique among all :class:`WlSeat` globals. The + name is only guaranteed to be unique for the current compositor + instance. + + The same seat names are used for all clients. Thus, the name can be + shared across processes to refer to a specific :class:`WlSeat` global. + + The name event is sent after binding to the seat global. This event is + only sent once per seat object, and the name does not change over the + lifetime of the :class:`WlSeat` global. + + Compositors may re-use the same seat name if the :class:`WlSeat` global + is destroyed and re-created later. + + :param name: + seat identifier + :type name: + `ArgumentType.String` + """ + self._post_event(1, name) + + +class WlSeatGlobal(Global): + interface = WlSeat + + +WlSeat._gen_c() +WlSeat.proxy_class = WlSeatProxy +WlSeat.resource_class = WlSeatResource +WlSeat.global_class = WlSeatGlobal diff --git a/bar/generated/wayland/wl_shell.py b/bar/generated/wayland/wl_shell.py new file mode 100644 index 0000000..4568b23 --- /dev/null +++ b/bar/generated/wayland/wl_shell.py @@ -0,0 +1,106 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_shell_surface import WlShellSurface +from .wl_surface import WlSurface + + +class WlShell(Interface): + """Create desktop-style surfaces + + This interface is implemented by servers that provide desktop-style user + interfaces. + + It allows clients to associate a + :class:`~pywayland.protocol.wayland.WlShellSurface` with a basic surface. + + Note! This protocol is deprecated and not intended for production use. For + desktop-style user interfaces, use xdg_shell. Compositors and clients + should not implement this interface. + """ + + name = "wl_shell" + version = 1 + + class error(enum.IntEnum): + role = 0 + + +class WlShellProxy(Proxy[WlShell]): + interface = WlShell + + @WlShell.request( + Argument(ArgumentType.NewId, interface=WlShellSurface), + Argument(ArgumentType.Object, interface=WlSurface), + ) + def get_shell_surface(self, surface: WlSurface) -> Proxy[WlShellSurface]: + """Create a shell surface from a surface + + Create a shell surface for an existing surface. This gives the + :class:`~pywayland.protocol.wayland.WlSurface` the role of a shell + surface. If the :class:`~pywayland.protocol.wayland.WlSurface` already + has another role, it raises a protocol error. + + Only one shell surface can be associated with a given surface. + + :param surface: + surface to be given the shell surface role + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + :returns: + :class:`~pywayland.protocol.wayland.WlShellSurface` -- shell + surface to create + """ + id = self._marshal_constructor(0, WlShellSurface, surface) + return id + + +class WlShellResource(Resource): + interface = WlShell + + +class WlShellGlobal(Global): + interface = WlShell + + +WlShell._gen_c() +WlShell.proxy_class = WlShellProxy +WlShell.resource_class = WlShellResource +WlShell.global_class = WlShellGlobal diff --git a/bar/generated/wayland/wl_shell_surface.py b/bar/generated/wayland/wl_shell_surface.py new file mode 100644 index 0000000..a06c500 --- /dev/null +++ b/bar/generated/wayland/wl_shell_surface.py @@ -0,0 +1,463 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_output import WlOutput +from .wl_seat import WlSeat +from .wl_surface import WlSurface + + +class WlShellSurface(Interface): + """Desktop-style metadata interface + + An interface that may be implemented by a + :class:`~pywayland.protocol.wayland.WlSurface`, for implementations that + provide a desktop-style user interface. + + It provides requests to treat surfaces like toplevel, fullscreen or popup + windows, move, resize or maximize them, associate metadata like title and + class, etc. + + On the server side the object is automatically destroyed when the related + :class:`~pywayland.protocol.wayland.WlSurface` is destroyed. On the client + side, wl_shell_surface_destroy() must be called before destroying the + :class:`~pywayland.protocol.wayland.WlSurface` object. + """ + + name = "wl_shell_surface" + version = 1 + + class resize(enum.IntFlag): + none = 0 + top = 1 + bottom = 2 + left = 4 + top_left = 5 + bottom_left = 6 + right = 8 + top_right = 9 + bottom_right = 10 + + class transient(enum.IntFlag): + inactive = 0x1 + + class fullscreen_method(enum.IntEnum): + default = 0 + scale = 1 + driver = 2 + fill = 3 + + +class WlShellSurfaceProxy(Proxy[WlShellSurface]): + interface = WlShellSurface + + @WlShellSurface.request( + Argument(ArgumentType.Uint), + ) + def pong(self, serial: int) -> None: + """Respond to a ping event + + A client must respond to a ping event with a pong request or the client + may be deemed unresponsive. + + :param serial: + serial number of the ping event + :type serial: + `ArgumentType.Uint` + """ + self._marshal(0, serial) + + @WlShellSurface.request( + Argument(ArgumentType.Object, interface=WlSeat), + Argument(ArgumentType.Uint), + ) + def move(self, seat: WlSeat, serial: int) -> None: + """Start an interactive move + + Start a pointer-driven move of the surface. + + This request must be used in response to a button press event. The + server may ignore move requests depending on the state of the surface + (e.g. fullscreen or maximized). + + :param seat: + seat whose pointer is used + :type seat: + :class:`~pywayland.protocol.wayland.WlSeat` + :param serial: + serial number of the implicit grab on the pointer + :type serial: + `ArgumentType.Uint` + """ + self._marshal(1, seat, serial) + + @WlShellSurface.request( + Argument(ArgumentType.Object, interface=WlSeat), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + ) + def resize(self, seat: WlSeat, serial: int, edges: int) -> None: + """Start an interactive resize + + Start a pointer-driven resizing of the surface. + + This request must be used in response to a button press event. The + server may ignore resize requests depending on the state of the surface + (e.g. fullscreen or maximized). + + :param seat: + seat whose pointer is used + :type seat: + :class:`~pywayland.protocol.wayland.WlSeat` + :param serial: + serial number of the implicit grab on the pointer + :type serial: + `ArgumentType.Uint` + :param edges: + which edge or corner is being dragged + :type edges: + `ArgumentType.Uint` + """ + self._marshal(2, seat, serial, edges) + + @WlShellSurface.request() + def set_toplevel(self) -> None: + """Make the surface a toplevel surface + + Map the surface as a toplevel surface. + + A toplevel surface is not fullscreen, maximized or transient. + """ + self._marshal(3) + + @WlShellSurface.request( + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Uint), + ) + def set_transient(self, parent: WlSurface, x: int, y: int, flags: int) -> None: + """Make the surface a transient surface + + Map the surface relative to an existing surface. + + The x and y arguments specify the location of the upper left corner of + the surface relative to the upper left corner of the parent surface, in + surface-local coordinates. + + The flags argument controls details of the transient behaviour. + + :param parent: + parent surface + :type parent: + :class:`~pywayland.protocol.wayland.WlSurface` + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Int` + :param flags: + transient surface behavior + :type flags: + `ArgumentType.Uint` + """ + self._marshal(4, parent, x, y, flags) + + @WlShellSurface.request( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlOutput, nullable=True), + ) + def set_fullscreen(self, method: int, framerate: int, output: WlOutput | None) -> None: + """Make the surface a fullscreen surface + + Map the surface as a fullscreen surface. + + If an output parameter is given then the surface will be made + fullscreen on that output. If the client does not specify the output + then the compositor will apply its policy - usually choosing the output + on which the surface has the biggest surface area. + + The client may specify a method to resolve a size conflict between the + output size and the surface size - this is provided through the method + parameter. + + The framerate parameter is used only when the method is set to + "driver", to indicate the preferred framerate. A value of 0 indicates + that the client does not care about framerate. The framerate is + specified in mHz, that is framerate of 60000 is 60Hz. + + A method of "scale" or "driver" implies a scaling operation of the + surface, either via a direct scaling operation or a change of the + output mode. This will override any kind of output scaling, so that + mapping a surface with a buffer size equal to the mode can fill the + screen independent of buffer_scale. + + A method of "fill" means we don't scale up the buffer, however any + output scale is applied. This means that you may run into an edge case + where the application maps a buffer with the same size of the output + mode but buffer_scale 1 (thus making a surface larger than the output). + In this case it is allowed to downscale the results to fit the screen. + + The compositor must reply to this request with a configure event with + the dimensions for the output on which the surface will be made + fullscreen. + + :param method: + method for resolving size conflict + :type method: + `ArgumentType.Uint` + :param framerate: + framerate in mHz + :type framerate: + `ArgumentType.Uint` + :param output: + output on which the surface is to be fullscreen + :type output: + :class:`~pywayland.protocol.wayland.WlOutput` or `None` + """ + self._marshal(5, method, framerate, output) + + @WlShellSurface.request( + Argument(ArgumentType.Object, interface=WlSeat), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Uint), + ) + def set_popup(self, seat: WlSeat, serial: int, parent: WlSurface, x: int, y: int, flags: int) -> None: + """Make the surface a popup surface + + Map the surface as a popup. + + A popup surface is a transient surface with an added pointer grab. + + An existing implicit grab will be changed to owner-events mode, and the + popup grab will continue after the implicit grab ends (i.e. releasing + the mouse button does not cause the popup to be unmapped). + + The popup grab continues until the window is destroyed or a mouse + button is pressed in any other client's window. A click in any of the + client's surfaces is reported as normal, however, clicks in other + clients' surfaces will be discarded and trigger the callback. + + The x and y arguments specify the location of the upper left corner of + the surface relative to the upper left corner of the parent surface, in + surface-local coordinates. + + :param seat: + seat whose pointer is used + :type seat: + :class:`~pywayland.protocol.wayland.WlSeat` + :param serial: + serial number of the implicit grab on the pointer + :type serial: + `ArgumentType.Uint` + :param parent: + parent surface + :type parent: + :class:`~pywayland.protocol.wayland.WlSurface` + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Int` + :param flags: + transient surface behavior + :type flags: + `ArgumentType.Uint` + """ + self._marshal(6, seat, serial, parent, x, y, flags) + + @WlShellSurface.request( + Argument(ArgumentType.Object, interface=WlOutput, nullable=True), + ) + def set_maximized(self, output: WlOutput | None) -> None: + """Make the surface a maximized surface + + Map the surface as a maximized surface. + + If an output parameter is given then the surface will be maximized on + that output. If the client does not specify the output then the + compositor will apply its policy - usually choosing the output on which + the surface has the biggest surface area. + + The compositor will reply with a configure event telling the expected + new surface size. The operation is completed on the next buffer attach + to this surface. + + A maximized surface typically fills the entire output it is bound to, + except for desktop elements such as panels. This is the main difference + between a maximized shell surface and a fullscreen shell surface. + + The details depend on the compositor implementation. + + :param output: + output on which the surface is to be maximized + :type output: + :class:`~pywayland.protocol.wayland.WlOutput` or `None` + """ + self._marshal(7, output) + + @WlShellSurface.request( + Argument(ArgumentType.String), + ) + def set_title(self, title: str) -> None: + """Set surface title + + Set a short title for the surface. + + This string may be used to identify the surface in a task bar, window + list, or other user interface elements provided by the compositor. + + The string must be encoded in UTF-8. + + :param title: + surface title + :type title: + `ArgumentType.String` + """ + self._marshal(8, title) + + @WlShellSurface.request( + Argument(ArgumentType.String), + ) + def set_class(self, class_: str) -> None: + """Set surface class + + Set a class for the surface. + + The surface class identifies the general class of applications to which + the surface belongs. A common convention is to use the file name (or + the full path if it is a non-standard location) of the application's + .desktop file as the class. + + :param class_: + surface class + :type class_: + `ArgumentType.String` + """ + self._marshal(9, class_) + + +class WlShellSurfaceResource(Resource): + interface = WlShellSurface + + @WlShellSurface.event( + Argument(ArgumentType.Uint), + ) + def ping(self, serial: int) -> None: + """Ping client + + Ping a client to check if it is receiving events and sending requests. + A client is expected to reply with a pong request. + + :param serial: + serial number of the ping + :type serial: + `ArgumentType.Uint` + """ + self._post_event(0, serial) + + @WlShellSurface.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def configure(self, edges: int, width: int, height: int) -> None: + """Suggest resize + + The configure event asks the client to resize its surface. + + The size is a hint, in the sense that the client is free to ignore it + if it doesn't resize, pick a smaller size (to satisfy aspect ratio or + resize in steps of NxM pixels). + + The edges parameter provides a hint about how the surface was resized. + The client may use this information to decide how to adjust its content + to the new size (e.g. a scrolling area might adjust its content + position to leave the viewable content unmoved). + + The client is free to dismiss all but the last configure event it + received. + + The width and height arguments specify the size of the window in + surface-local coordinates. + + :param edges: + how the surface was resized + :type edges: + `ArgumentType.Uint` + :param width: + new width of the surface + :type width: + `ArgumentType.Int` + :param height: + new height of the surface + :type height: + `ArgumentType.Int` + """ + self._post_event(1, edges, width, height) + + @WlShellSurface.event() + def popup_done(self) -> None: + """Popup interaction is done + + The popup_done event is sent out when a popup grab is broken, that is, + when the user clicks a surface that doesn't belong to the client owning + the popup surface. + """ + self._post_event(2) + + +class WlShellSurfaceGlobal(Global): + interface = WlShellSurface + + +WlShellSurface._gen_c() +WlShellSurface.proxy_class = WlShellSurfaceProxy +WlShellSurface.resource_class = WlShellSurfaceResource +WlShellSurface.global_class = WlShellSurfaceGlobal diff --git a/bar/generated/wayland/wl_shm.py b/bar/generated/wayland/wl_shm.py new file mode 100644 index 0000000..1a7dcd8 --- /dev/null +++ b/bar/generated/wayland/wl_shm.py @@ -0,0 +1,235 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_shm_pool import WlShmPool + + +class WlShm(Interface): + """Shared memory support + + A singleton global object that provides support for shared memory. + + Clients can create :class:`~pywayland.protocol.wayland.WlShmPool` objects + using the create_pool request. + + On binding the :class:`WlShm` object one or more format events are emitted + to inform clients about the valid pixel formats that can be used for + buffers. + """ + + name = "wl_shm" + version = 1 + + class error(enum.IntEnum): + invalid_format = 0 + invalid_stride = 1 + invalid_fd = 2 + + class format(enum.IntEnum): + argb8888 = 0 + xrgb8888 = 1 + c8 = 0x20203843 + rgb332 = 0x38424752 + bgr233 = 0x38524742 + xrgb4444 = 0x32315258 + xbgr4444 = 0x32314258 + rgbx4444 = 0x32315852 + bgrx4444 = 0x32315842 + argb4444 = 0x32315241 + abgr4444 = 0x32314241 + rgba4444 = 0x32314152 + bgra4444 = 0x32314142 + xrgb1555 = 0x35315258 + xbgr1555 = 0x35314258 + rgbx5551 = 0x35315852 + bgrx5551 = 0x35315842 + argb1555 = 0x35315241 + abgr1555 = 0x35314241 + rgba5551 = 0x35314152 + bgra5551 = 0x35314142 + rgb565 = 0x36314752 + bgr565 = 0x36314742 + rgb888 = 0x34324752 + bgr888 = 0x34324742 + xbgr8888 = 0x34324258 + rgbx8888 = 0x34325852 + bgrx8888 = 0x34325842 + abgr8888 = 0x34324241 + rgba8888 = 0x34324152 + bgra8888 = 0x34324142 + xrgb2101010 = 0x30335258 + xbgr2101010 = 0x30334258 + rgbx1010102 = 0x30335852 + bgrx1010102 = 0x30335842 + argb2101010 = 0x30335241 + abgr2101010 = 0x30334241 + rgba1010102 = 0x30334152 + bgra1010102 = 0x30334142 + yuyv = 0x56595559 + yvyu = 0x55595659 + uyvy = 0x59565955 + vyuy = 0x59555956 + ayuv = 0x56555941 + nv12 = 0x3231564E + nv21 = 0x3132564E + nv16 = 0x3631564E + nv61 = 0x3136564E + yuv410 = 0x39565559 + yvu410 = 0x39555659 + yuv411 = 0x31315559 + yvu411 = 0x31315659 + yuv420 = 0x32315559 + yvu420 = 0x32315659 + yuv422 = 0x36315559 + yvu422 = 0x36315659 + yuv444 = 0x34325559 + yvu444 = 0x34325659 + r8 = 0x20203852 + r16 = 0x20363152 + rg88 = 0x38384752 + gr88 = 0x38385247 + rg1616 = 0x32334752 + gr1616 = 0x32335247 + xrgb16161616f = 0x48345258 + xbgr16161616f = 0x48344258 + argb16161616f = 0x48345241 + abgr16161616f = 0x48344241 + xyuv8888 = 0x56555958 + vuy888 = 0x34325556 + vuy101010 = 0x30335556 + y210 = 0x30313259 + y212 = 0x32313259 + y216 = 0x36313259 + y410 = 0x30313459 + y412 = 0x32313459 + y416 = 0x36313459 + xvyu2101010 = 0x30335658 + xvyu12_16161616 = 0x36335658 + xvyu16161616 = 0x38345658 + y0l0 = 0x304C3059 + x0l0 = 0x304C3058 + y0l2 = 0x324C3059 + x0l2 = 0x324C3058 + yuv420_8bit = 0x38305559 + yuv420_10bit = 0x30315559 + xrgb8888_a8 = 0x38415258 + xbgr8888_a8 = 0x38414258 + rgbx8888_a8 = 0x38415852 + bgrx8888_a8 = 0x38415842 + rgb888_a8 = 0x38413852 + bgr888_a8 = 0x38413842 + rgb565_a8 = 0x38413552 + bgr565_a8 = 0x38413542 + nv24 = 0x3432564E + nv42 = 0x3234564E + p210 = 0x30313250 + p010 = 0x30313050 + p012 = 0x32313050 + p016 = 0x36313050 + axbxgxrx106106106106 = 0x30314241 + nv15 = 0x3531564E + q410 = 0x30313451 + q401 = 0x31303451 + xrgb16161616 = 0x38345258 + xbgr16161616 = 0x38344258 + argb16161616 = 0x38345241 + abgr16161616 = 0x38344241 + + +class WlShmProxy(Proxy[WlShm]): + interface = WlShm + + @WlShm.request( + Argument(ArgumentType.NewId, interface=WlShmPool), + Argument(ArgumentType.FileDescriptor), + Argument(ArgumentType.Int), + ) + def create_pool(self, fd: int, size: int) -> Proxy[WlShmPool]: + """Create a shm pool + + Create a new :class:`~pywayland.protocol.wayland.WlShmPool` object. + + The pool can be used to create shared memory based buffer objects. The + server will mmap size bytes of the passed file descriptor, to use as + backing memory for the pool. + + :param fd: + file descriptor for the pool + :type fd: + `ArgumentType.FileDescriptor` + :param size: + pool size, in bytes + :type size: + `ArgumentType.Int` + :returns: + :class:`~pywayland.protocol.wayland.WlShmPool` -- pool to create + """ + id = self._marshal_constructor(0, WlShmPool, fd, size) + return id + + +class WlShmResource(Resource): + interface = WlShm + + @WlShm.event( + Argument(ArgumentType.Uint), + ) + def format(self, format: int) -> None: + """Pixel format description + + Informs the client about a valid pixel format that can be used for + buffers. Known formats include argb8888 and xrgb8888. + + :param format: + buffer pixel format + :type format: + `ArgumentType.Uint` + """ + self._post_event(0, format) + + +class WlShmGlobal(Global): + interface = WlShm + + +WlShm._gen_c() +WlShm.proxy_class = WlShmProxy +WlShm.resource_class = WlShmResource +WlShm.global_class = WlShmGlobal diff --git a/bar/generated/wayland/wl_shm_pool.py b/bar/generated/wayland/wl_shm_pool.py new file mode 100644 index 0000000..4b06359 --- /dev/null +++ b/bar/generated/wayland/wl_shm_pool.py @@ -0,0 +1,159 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_buffer import WlBuffer + + +class WlShmPool(Interface): + """A shared memory pool + + The :class:`WlShmPool` object encapsulates a piece of memory shared between + the compositor and client. Through the :class:`WlShmPool` object, the + client can allocate shared memory + :class:`~pywayland.protocol.wayland.WlBuffer` objects. All objects created + through the same pool share the same underlying mapped memory. Reusing the + mapped memory avoids the setup/teardown overhead and is useful when + interactively resizing a surface or for many small buffers. + """ + + name = "wl_shm_pool" + version = 1 + + +class WlShmPoolProxy(Proxy[WlShmPool]): + interface = WlShmPool + + @WlShmPool.request( + Argument(ArgumentType.NewId, interface=WlBuffer), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Uint), + ) + def create_buffer(self, offset: int, width: int, height: int, stride: int, format: int) -> Proxy[WlBuffer]: + """Create a buffer from the pool + + Create a :class:`~pywayland.protocol.wayland.WlBuffer` object from the + pool. + + The buffer is created offset bytes into the pool and has width and + height as specified. The stride argument specifies the number of bytes + from the beginning of one row to the beginning of the next. The format + is the pixel format of the buffer and must be one of those advertised + through the :func:`WlShm.format() + ` event. + + A buffer will keep a reference to the pool it was created from so it is + valid to destroy the pool immediately after creating a buffer from it. + + :param offset: + buffer byte offset within the pool + :type offset: + `ArgumentType.Int` + :param width: + buffer width, in pixels + :type width: + `ArgumentType.Int` + :param height: + buffer height, in pixels + :type height: + `ArgumentType.Int` + :param stride: + number of bytes from the beginning of one row to the beginning of + the next row + :type stride: + `ArgumentType.Int` + :param format: + buffer pixel format + :type format: + `ArgumentType.Uint` + :returns: + :class:`~pywayland.protocol.wayland.WlBuffer` -- buffer to create + """ + id = self._marshal_constructor(0, WlBuffer, offset, width, height, stride, format) + return id + + @WlShmPool.request() + def destroy(self) -> None: + """Destroy the pool + + Destroy the shared memory pool. + + The mmapped memory will be released when all buffers that have been + created from this pool are gone. + """ + self._marshal(1) + self._destroy() + + @WlShmPool.request( + Argument(ArgumentType.Int), + ) + def resize(self, size: int) -> None: + """Change the size of the pool mapping + + This request will cause the server to remap the backing memory for the + pool from the file descriptor passed when the pool was created, but + using the new size. This request can only be used to make the pool + bigger. + + This request only changes the amount of bytes that are mmapped by the + server and does not touch the file corresponding to the file descriptor + passed at creation time. It is the client's responsibility to ensure + that the file is at least as big as the new pool size. + + :param size: + new size of the pool, in bytes + :type size: + `ArgumentType.Int` + """ + self._marshal(2, size) + + +class WlShmPoolResource(Resource): + interface = WlShmPool + + +class WlShmPoolGlobal(Global): + interface = WlShmPool + + +WlShmPool._gen_c() +WlShmPool.proxy_class = WlShmPoolProxy +WlShmPool.resource_class = WlShmPoolResource +WlShmPool.global_class = WlShmPoolGlobal diff --git a/bar/generated/wayland/wl_subcompositor.py b/bar/generated/wayland/wl_subcompositor.py new file mode 100644 index 0000000..12e337a --- /dev/null +++ b/bar/generated/wayland/wl_subcompositor.py @@ -0,0 +1,150 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_subsurface import WlSubsurface +from .wl_surface import WlSurface + + +class WlSubcompositor(Interface): + """Sub-surface compositing + + The global interface exposing sub-surface compositing capabilities. A + :class:`~pywayland.protocol.wayland.WlSurface`, that has sub-surfaces + associated, is called the parent surface. Sub-surfaces can be arbitrarily + nested and create a tree of sub-surfaces. + + The root surface in a tree of sub-surfaces is the main surface. The main + surface cannot be a sub-surface, because sub-surfaces must always have a + parent. + + A main surface with its sub-surfaces forms a (compound) window. For window + management purposes, this set of + :class:`~pywayland.protocol.wayland.WlSurface` objects is to be considered + as a single window, and it should also behave as such. + + The aim of sub-surfaces is to offload some of the compositing work within a + window from clients to the compositor. A prime example is a video player + with decorations and video in separate + :class:`~pywayland.protocol.wayland.WlSurface` objects. This should allow + the compositor to pass YUV video buffer processing to dedicated overlay + hardware when possible. + """ + + name = "wl_subcompositor" + version = 1 + + class error(enum.IntEnum): + bad_surface = 0 + bad_parent = 1 + + +class WlSubcompositorProxy(Proxy[WlSubcompositor]): + interface = WlSubcompositor + + @WlSubcompositor.request() + def destroy(self) -> None: + """Unbind from the subcompositor interface + + Informs the server that the client will not be using this protocol + object anymore. This does not affect any other objects, + :class:`~pywayland.protocol.wayland.WlSubsurface` objects included. + """ + self._marshal(0) + self._destroy() + + @WlSubcompositor.request( + Argument(ArgumentType.NewId, interface=WlSubsurface), + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Object, interface=WlSurface), + ) + def get_subsurface(self, surface: WlSurface, parent: WlSurface) -> Proxy[WlSubsurface]: + """Give a surface the role sub-surface + + Create a sub-surface interface for the given surface, and associate it + with the given parent surface. This turns a plain + :class:`~pywayland.protocol.wayland.WlSurface` into a sub-surface. + + The to-be sub-surface must not already have another role, and it must + not have an existing :class:`~pywayland.protocol.wayland.WlSubsurface` + object. Otherwise the bad_surface protocol error is raised. + + Adding sub-surfaces to a parent is a double-buffered operation on the + parent (see :func:`WlSurface.commit() + `). The effect of adding a + sub-surface becomes visible on the next time the state of the parent + surface is applied. + + The parent surface must not be one of the child surface's descendants, + and the parent must be different from the child surface, otherwise the + bad_parent protocol error is raised. + + This request modifies the behaviour of :func:`WlSurface.commit() + ` request on the sub- + surface, see the documentation on + :class:`~pywayland.protocol.wayland.WlSubsurface` interface. + + :param surface: + the surface to be turned into a sub-surface + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + :param parent: + the parent surface + :type parent: + :class:`~pywayland.protocol.wayland.WlSurface` + :returns: + :class:`~pywayland.protocol.wayland.WlSubsurface` -- the new sub- + surface object ID + """ + id = self._marshal_constructor(1, WlSubsurface, surface, parent) + return id + + +class WlSubcompositorResource(Resource): + interface = WlSubcompositor + + +class WlSubcompositorGlobal(Global): + interface = WlSubcompositor + + +WlSubcompositor._gen_c() +WlSubcompositor.proxy_class = WlSubcompositorProxy +WlSubcompositor.resource_class = WlSubcompositorResource +WlSubcompositor.global_class = WlSubcompositorGlobal diff --git a/bar/generated/wayland/wl_subsurface.py b/bar/generated/wayland/wl_subsurface.py new file mode 100644 index 0000000..3b7738d --- /dev/null +++ b/bar/generated/wayland/wl_subsurface.py @@ -0,0 +1,271 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_surface import WlSurface + + +class WlSubsurface(Interface): + """Sub-surface interface to a :class:`~pywayland.protocol.wayland.WlSurface` + + An additional interface to a :class:`~pywayland.protocol.wayland.WlSurface` + object, which has been made a sub-surface. A sub-surface has one parent + surface. A sub-surface's size and position are not limited to that of the + parent. Particularly, a sub-surface is not automatically clipped to its + parent's area. + + A sub-surface becomes mapped, when a non-NULL + :class:`~pywayland.protocol.wayland.WlBuffer` is applied and the parent + surface is mapped. The order of which one happens first is irrelevant. A + sub-surface is hidden if the parent becomes hidden, or if a NULL + :class:`~pywayland.protocol.wayland.WlBuffer` is applied. These rules apply + recursively through the tree of surfaces. + + The behaviour of a :func:`WlSurface.commit() + ` request on a sub-surface + depends on the sub-surface's mode. The possible modes are synchronized and + desynchronized, see methods :func:`WlSubsurface.set_sync()` and + :func:`WlSubsurface.set_desync()`. Synchronized mode caches the + :class:`~pywayland.protocol.wayland.WlSurface` state to be applied when the + parent's state gets applied, and desynchronized mode applies the pending + :class:`~pywayland.protocol.wayland.WlSurface` state directly. A sub- + surface is initially in the synchronized mode. + + Sub-surfaces also have another kind of state, which is managed by + :class:`WlSubsurface` requests, as opposed to + :class:`~pywayland.protocol.wayland.WlSurface` requests. This state + includes the sub-surface position relative to the parent surface + (:func:`WlSubsurface.set_position()`), and the stacking order of the parent + and its sub-surfaces (:func:`WlSubsurface.place_above()` and .place_below). + This state is applied when the parent surface's + :class:`~pywayland.protocol.wayland.WlSurface` state is applied, regardless + of the sub-surface's mode. As the exception, set_sync and set_desync are + effective immediately. + + The main surface can be thought to be always in desynchronized mode, since + it does not have a parent in the sub-surfaces sense. + + Even if a sub-surface is in desynchronized mode, it will behave as in + synchronized mode, if its parent surface behaves as in synchronized mode. + This rule is applied recursively throughout the tree of surfaces. This + means, that one can set a sub-surface into synchronized mode, and then + assume that all its child and grand-child sub-surfaces are synchronized, + too, without explicitly setting them. + + Destroying a sub-surface takes effect immediately. If you need to + synchronize the removal of a sub-surface to the parent surface update, + unmap the sub-surface first by attaching a NULL + :class:`~pywayland.protocol.wayland.WlBuffer`, update parent, and then + destroy the sub-surface. + + If the parent :class:`~pywayland.protocol.wayland.WlSurface` object is + destroyed, the sub-surface is unmapped. + """ + + name = "wl_subsurface" + version = 1 + + class error(enum.IntEnum): + bad_surface = 0 + + +class WlSubsurfaceProxy(Proxy[WlSubsurface]): + interface = WlSubsurface + + @WlSubsurface.request() + def destroy(self) -> None: + """Remove sub-surface interface + + The sub-surface interface is removed from the + :class:`~pywayland.protocol.wayland.WlSurface` object that was turned + into a sub-surface with a :func:`WlSubcompositor.get_subsurface() + ` request. + The wl_surface's association to the parent is deleted. The + :class:`~pywayland.protocol.wayland.WlSurface` is unmapped immediately. + """ + self._marshal(0) + self._destroy() + + @WlSubsurface.request( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def set_position(self, x: int, y: int) -> None: + """Reposition the sub-surface + + This schedules a sub-surface position change. The sub-surface will be + moved so that its origin (top left corner pixel) will be at the + location x, y of the parent surface coordinate system. The coordinates + are not restricted to the parent surface area. Negative values are + allowed. + + The scheduled coordinates will take effect whenever the state of the + parent surface is applied. When this happens depends on whether the + parent surface is in synchronized mode or not. See + :func:`WlSubsurface.set_sync()` and :func:`WlSubsurface.set_desync()` + for details. + + If more than one set_position request is invoked by the client before + the commit of the parent surface, the position of a new request always + replaces the scheduled position from any previous request. + + The initial position is 0, 0. + + :param x: + x coordinate in the parent surface + :type x: + `ArgumentType.Int` + :param y: + y coordinate in the parent surface + :type y: + `ArgumentType.Int` + """ + self._marshal(1, x, y) + + @WlSubsurface.request( + Argument(ArgumentType.Object, interface=WlSurface), + ) + def place_above(self, sibling: WlSurface) -> None: + """Restack the sub-surface + + This sub-surface is taken from the stack, and put back just above the + reference surface, changing the z-order of the sub-surfaces. The + reference surface must be one of the sibling surfaces, or the parent + surface. Using any other surface, including this sub-surface, will + cause a protocol error. + + The z-order is double-buffered. Requests are handled in order and + applied immediately to a pending state. The final pending state is + copied to the active state the next time the state of the parent + surface is applied. When this happens depends on whether the parent + surface is in synchronized mode or not. See + :func:`WlSubsurface.set_sync()` and :func:`WlSubsurface.set_desync()` + for details. + + A new sub-surface is initially added as the top-most in the stack of + its siblings and parent. + + :param sibling: + the reference surface + :type sibling: + :class:`~pywayland.protocol.wayland.WlSurface` + """ + self._marshal(2, sibling) + + @WlSubsurface.request( + Argument(ArgumentType.Object, interface=WlSurface), + ) + def place_below(self, sibling: WlSurface) -> None: + """Restack the sub-surface + + The sub-surface is placed just below the reference surface. See + :func:`WlSubsurface.place_above()`. + + :param sibling: + the reference surface + :type sibling: + :class:`~pywayland.protocol.wayland.WlSurface` + """ + self._marshal(3, sibling) + + @WlSubsurface.request() + def set_sync(self) -> None: + """Set sub-surface to synchronized mode + + Change the commit behaviour of the sub-surface to synchronized mode, + also described as the parent dependent mode. + + In synchronized mode, :func:`WlSurface.commit() + ` on a sub-surface will + accumulate the committed state in a cache, but the state will not be + applied and hence will not change the compositor output. The cached + state is applied to the sub-surface immediately after the parent + surface's state is applied. This ensures atomic updates of the parent + and all its synchronized sub-surfaces. Applying the cached state will + invalidate the cache, so further parent surface commits do not + (re-)apply old state. + + See :class:`WlSubsurface` for the recursive effect of this mode. + """ + self._marshal(4) + + @WlSubsurface.request() + def set_desync(self) -> None: + """Set sub-surface to desynchronized mode + + Change the commit behaviour of the sub-surface to desynchronized mode, + also described as independent or freely running mode. + + In desynchronized mode, :func:`WlSurface.commit() + ` on a sub-surface will + apply the pending state directly, without caching, as happens normally + with a :class:`~pywayland.protocol.wayland.WlSurface`. Calling + :func:`WlSurface.commit() + ` on the parent surface + has no effect on the sub-surface's + :class:`~pywayland.protocol.wayland.WlSurface` state. This mode allows + a sub-surface to be updated on its own. + + If cached state exists when :func:`WlSurface.commit() + ` is called in + desynchronized mode, the pending state is added to the cached state, + and applied as a whole. This invalidates the cache. + + Note: even if a sub-surface is set to desynchronized, a parent sub- + surface may override it to behave as synchronized. For details, see + :class:`WlSubsurface`. + + If a surface's parent surface behaves as desynchronized, then the + cached state is applied on set_desync. + """ + self._marshal(5) + + +class WlSubsurfaceResource(Resource): + interface = WlSubsurface + + +class WlSubsurfaceGlobal(Global): + interface = WlSubsurface + + +WlSubsurface._gen_c() +WlSubsurface.proxy_class = WlSubsurfaceProxy +WlSubsurface.resource_class = WlSubsurfaceResource +WlSubsurface.global_class = WlSubsurfaceGlobal diff --git a/bar/generated/wayland/wl_surface.py b/bar/generated/wayland/wl_surface.py new file mode 100644 index 0000000..df78b34 --- /dev/null +++ b/bar/generated/wayland/wl_surface.py @@ -0,0 +1,704 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +import enum + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_buffer import WlBuffer +from .wl_callback import WlCallback +from .wl_output import WlOutput +from .wl_region import WlRegion + + +class WlSurface(Interface): + """An onscreen surface + + A surface is a rectangular area that may be displayed on zero or more + outputs, and shown any number of times at the compositor's discretion. They + can present wl_buffers, receive user input, and define a local coordinate + system. + + The size of a surface (and relative positions on it) is described in + surface-local coordinates, which may differ from the buffer coordinates of + the pixel content, in case a buffer_transform or a buffer_scale is used. + + A surface without a "role" is fairly useless: a compositor does not know + where, when or how to present it. The role is the purpose of a + :class:`WlSurface`. Examples of roles are a cursor for a pointer (as set by + :func:`WlPointer.set_cursor() + `), a drag icon + (:func:`WlDataDevice.start_drag() + `), a sub-surface + (:func:`WlSubcompositor.get_subsurface() + `), and a window + as defined by a shell protocol (e.g. :func:`WlShell.get_shell_surface() + `). + + A surface can have only one role at a time. Initially a :class:`WlSurface` + does not have a role. Once a :class:`WlSurface` is given a role, it is set + permanently for the whole lifetime of the :class:`WlSurface` object. Giving + the current role again is allowed, unless explicitly forbidden by the + relevant interface specification. + + Surface roles are given by requests in other interfaces such as + :func:`WlPointer.set_cursor() + `. The request should + explicitly mention that this request gives a role to a :class:`WlSurface`. + Often, this request also creates a new protocol object that represents the + role and adds additional functionality to :class:`WlSurface`. When a client + wants to destroy a :class:`WlSurface`, they must destroy this role object + before the :class:`WlSurface`, otherwise a defunct_role_object error is + sent. + + Destroying the role object does not remove the role from the + :class:`WlSurface`, but it may stop the :class:`WlSurface` from "playing + the role". For instance, if a + :class:`~pywayland.protocol.wayland.WlSubsurface` object is destroyed, the + :class:`WlSurface` it was created for will be unmapped and forget its + position and z-order. It is allowed to create a + :class:`~pywayland.protocol.wayland.WlSubsurface` for the same + :class:`WlSurface` again, but it is not allowed to use the + :class:`WlSurface` as a cursor (cursor is a different role than sub- + surface, and role switching is not allowed). + """ + + name = "wl_surface" + version = 6 + + class error(enum.IntEnum): + invalid_scale = 0 + invalid_transform = 1 + invalid_size = 2 + invalid_offset = 3 + defunct_role_object = 4 + + +class WlSurfaceProxy(Proxy[WlSurface]): + interface = WlSurface + + @WlSurface.request() + def destroy(self) -> None: + """Delete surface + + Deletes the surface and invalidates its object ID. + """ + self._marshal(0) + self._destroy() + + @WlSurface.request( + Argument(ArgumentType.Object, interface=WlBuffer, nullable=True), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def attach(self, buffer: WlBuffer | None, x: int, y: int) -> None: + """Set the surface contents + + Set a buffer as the content of this surface. + + The new size of the surface is calculated based on the buffer size + transformed by the inverse buffer_transform and the inverse + buffer_scale. This means that at commit time the supplied buffer size + must be an integer multiple of the buffer_scale. If that's not the + case, an invalid_size error is sent. + + The x and y arguments specify the location of the new pending buffer's + upper left corner, relative to the current buffer's upper left corner, + in surface-local coordinates. In other words, the x and y, combined + with the new surface size define in which directions the surface's size + changes. Setting anything other than 0 as x and y arguments is + discouraged, and should instead be replaced with using the separate + :func:`WlSurface.offset()` request. + + When the bound :class:`WlSurface` version is 5 or higher, passing any + non-zero x or y is a protocol violation, and will result in an + 'invalid_offset' error being raised. The x and y arguments are ignored + and do not change the pending state. To achieve equivalent semantics, + use :func:`WlSurface.offset()`. + + Surface contents are double-buffered state, see + :func:`WlSurface.commit()`. + + The initial surface contents are void; there is no content. + :func:`WlSurface.attach()` assigns the given + :class:`~pywayland.protocol.wayland.WlBuffer` as the pending + :class:`~pywayland.protocol.wayland.WlBuffer`. + :func:`WlSurface.commit()` makes the pending + :class:`~pywayland.protocol.wayland.WlBuffer` the new surface contents, + and the size of the surface becomes the size calculated from the + :class:`~pywayland.protocol.wayland.WlBuffer`, as described above. + After commit, there is no pending buffer until the next attach. + + Committing a pending :class:`~pywayland.protocol.wayland.WlBuffer` + allows the compositor to read the pixels in the + :class:`~pywayland.protocol.wayland.WlBuffer`. The compositor may + access the pixels at any time after the :func:`WlSurface.commit()` + request. When the compositor will not access the pixels anymore, it + will send the :func:`WlBuffer.release() + ` event. Only after + receiving :func:`WlBuffer.release() + `, the client may reuse + the :class:`~pywayland.protocol.wayland.WlBuffer`. A + :class:`~pywayland.protocol.wayland.WlBuffer` that has been attached + and then replaced by another attach instead of committed will not + receive a release event, and is not used by the compositor. + + If a pending :class:`~pywayland.protocol.wayland.WlBuffer` has been + committed to more than one :class:`WlSurface`, the delivery of + :func:`WlBuffer.release() + ` events becomes + undefined. A well behaved client should not rely on + :func:`WlBuffer.release() + ` events in this case. + Alternatively, a client could create multiple + :class:`~pywayland.protocol.wayland.WlBuffer` objects from the same + backing storage or use wp_linux_buffer_release. + + Destroying the :class:`~pywayland.protocol.wayland.WlBuffer` after + :func:`WlBuffer.release() + ` does not change the + surface contents. Destroying the + :class:`~pywayland.protocol.wayland.WlBuffer` before + :func:`WlBuffer.release() + ` is allowed as long as + the underlying buffer storage isn't re-used (this can happen e.g. on + client process termination). However, if the client destroys the + :class:`~pywayland.protocol.wayland.WlBuffer` before receiving the + :func:`WlBuffer.release() + ` event and mutates the + underlying buffer storage, the surface contents become undefined + immediately. + + If :func:`WlSurface.attach()` is sent with a NULL + :class:`~pywayland.protocol.wayland.WlBuffer`, the following + :func:`WlSurface.commit()` will remove the surface content. + + :param buffer: + buffer of surface contents + :type buffer: + :class:`~pywayland.protocol.wayland.WlBuffer` or `None` + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Int` + """ + self._marshal(1, buffer, x, y) + + @WlSurface.request( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + ) + def damage(self, x: int, y: int, width: int, height: int) -> None: + """Mark part of the surface damaged + + This request is used to describe the regions where the pending buffer + is different from the current surface contents, and where the surface + therefore needs to be repainted. The compositor ignores the parts of + the damage that fall outside of the surface. + + Damage is double-buffered state, see :func:`WlSurface.commit()`. + + The damage rectangle is specified in surface-local coordinates, where x + and y specify the upper left corner of the damage rectangle. + + The initial value for pending damage is empty: no damage. + :func:`WlSurface.damage()` adds pending damage: the new pending damage + is the union of old pending damage and the given rectangle. + + :func:`WlSurface.commit()` assigns pending damage as the current + damage, and clears pending damage. The server will clear the current + damage as it repaints the surface. + + Note! New clients should not use this request. Instead damage can be + posted with :func:`WlSurface.damage_buffer()` which uses buffer + coordinates instead of surface coordinates. + + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Int` + :param width: + width of damage rectangle + :type width: + `ArgumentType.Int` + :param height: + height of damage rectangle + :type height: + `ArgumentType.Int` + """ + self._marshal(2, x, y, width, height) + + @WlSurface.request( + Argument(ArgumentType.NewId, interface=WlCallback), + ) + def frame(self) -> Proxy[WlCallback]: + """Request a frame throttling hint + + Request a notification when it is a good time to start drawing a new + frame, by creating a frame callback. This is useful for throttling + redrawing operations, and driving animations. + + When a client is animating on a :class:`WlSurface`, it can use the + 'frame' request to get notified when it is a good time to draw and + commit the next frame of animation. If the client commits an update + earlier than that, it is likely that some updates will not make it to + the display, and the client is wasting resources by drawing too often. + + The frame request will take effect on the next + :func:`WlSurface.commit()`. The notification will only be posted for + one frame unless requested again. For a :class:`WlSurface`, the + notifications are posted in the order the frame requests were + committed. + + The server must send the notifications so that a client will not send + excessive updates, while still allowing the highest possible update + rate for clients that wait for the reply before drawing again. The + server should give some time for the client to draw and commit after + sending the frame callback events to let it hit the next output + refresh. + + A server should avoid signaling the frame callbacks if the surface is + not visible in any way, e.g. the surface is off-screen, or completely + obscured by other opaque surfaces. + + The object returned by this request will be destroyed by the compositor + after the callback is fired and as such the client must not attempt to + use it after that point. + + The callback_data passed in the callback is the current time, in + milliseconds, with an undefined base. + + :returns: + :class:`~pywayland.protocol.wayland.WlCallback` -- callback object + for the frame request + """ + callback = self._marshal_constructor(3, WlCallback) + return callback + + @WlSurface.request( + Argument(ArgumentType.Object, interface=WlRegion, nullable=True), + ) + def set_opaque_region(self, region: WlRegion | None) -> None: + """Set opaque region + + This request sets the region of the surface that contains opaque + content. + + The opaque region is an optimization hint for the compositor that lets + it optimize the redrawing of content behind opaque regions. Setting an + opaque region is not required for correct behaviour, but marking + transparent content as opaque will result in repaint artifacts. + + The opaque region is specified in surface-local coordinates. + + The compositor ignores the parts of the opaque region that fall outside + of the surface. + + Opaque region is double-buffered state, see :func:`WlSurface.commit()`. + + :func:`WlSurface.set_opaque_region()` changes the pending opaque + region. :func:`WlSurface.commit()` copies the pending region to the + current region. Otherwise, the pending and current regions are never + changed. + + The initial value for an opaque region is empty. Setting the pending + opaque region has copy semantics, and the + :class:`~pywayland.protocol.wayland.WlRegion` object can be destroyed + immediately. A NULL :class:`~pywayland.protocol.wayland.WlRegion` + causes the pending opaque region to be set to empty. + + :param region: + opaque region of the surface + :type region: + :class:`~pywayland.protocol.wayland.WlRegion` or `None` + """ + self._marshal(4, region) + + @WlSurface.request( + Argument(ArgumentType.Object, interface=WlRegion, nullable=True), + ) + def set_input_region(self, region: WlRegion | None) -> None: + """Set input region + + This request sets the region of the surface that can receive pointer + and touch events. + + Input events happening outside of this region will try the next surface + in the server surface stack. The compositor ignores the parts of the + input region that fall outside of the surface. + + The input region is specified in surface-local coordinates. + + Input region is double-buffered state, see :func:`WlSurface.commit()`. + + :func:`WlSurface.set_input_region()` changes the pending input region. + :func:`WlSurface.commit()` copies the pending region to the current + region. Otherwise the pending and current regions are never changed, + except cursor and icon surfaces are special cases, see + :func:`WlPointer.set_cursor() + ` and + :func:`WlDataDevice.start_drag() + `. + + The initial value for an input region is infinite. That means the whole + surface will accept input. Setting the pending input region has copy + semantics, and the :class:`~pywayland.protocol.wayland.WlRegion` object + can be destroyed immediately. A NULL + :class:`~pywayland.protocol.wayland.WlRegion` causes the input region + to be set to infinite. + + :param region: + input region of the surface + :type region: + :class:`~pywayland.protocol.wayland.WlRegion` or `None` + """ + self._marshal(5, region) + + @WlSurface.request() + def commit(self) -> None: + """Commit pending surface state + + Surface state (input, opaque, and damage regions, attached buffers, + etc.) is double-buffered. Protocol requests modify the pending state, + as opposed to the current state in use by the compositor. A commit + request atomically applies all pending state, replacing the current + state. After commit, the new pending state is as documented for each + related request. + + On commit, a pending :class:`~pywayland.protocol.wayland.WlBuffer` is + applied first, and all other state second. This means that all + coordinates in double-buffered state are relative to the new + :class:`~pywayland.protocol.wayland.WlBuffer` coming into use, except + for :func:`WlSurface.attach()` itself. If there is no pending + :class:`~pywayland.protocol.wayland.WlBuffer`, the coordinates are + relative to the current surface contents. + + All requests that need a commit to become effective are documented to + affect double-buffered state. + + Other interfaces may add further double-buffered surface state. + """ + self._marshal(6) + + @WlSurface.request( + Argument(ArgumentType.Int), + version=2, + ) + def set_buffer_transform(self, transform: int) -> None: + """Sets the buffer transformation + + This request sets an optional transformation on how the compositor + interprets the contents of the buffer attached to the surface. The + accepted values for the transform parameter are the values for + :func:`WlOutput.transform() + `. + + Buffer transform is double-buffered state, see + :func:`WlSurface.commit()`. + + A newly created surface has its buffer transformation set to normal. + + :func:`WlSurface.set_buffer_transform()` changes the pending buffer + transformation. :func:`WlSurface.commit()` copies the pending buffer + transformation to the current one. Otherwise, the pending and current + values are never changed. + + The purpose of this request is to allow clients to render content + according to the output transform, thus permitting the compositor to + use certain optimizations even if the display is rotated. Using + hardware overlays and scanning out a client buffer for fullscreen + surfaces are examples of such optimizations. Those optimizations are + highly dependent on the compositor implementation, so the use of this + request should be considered on a case-by-case basis. + + Note that if the transform value includes 90 or 270 degree rotation, + the width of the buffer will become the surface height and the height + of the buffer will become the surface width. + + If transform is not one of the values from the + :func:`WlOutput.transform() + ` enum the + invalid_transform protocol error is raised. + + :param transform: + transform for interpreting buffer contents + :type transform: + `ArgumentType.Int` + """ + self._marshal(7, transform) + + @WlSurface.request( + Argument(ArgumentType.Int), + version=3, + ) + def set_buffer_scale(self, scale: int) -> None: + """Sets the buffer scaling factor + + This request sets an optional scaling factor on how the compositor + interprets the contents of the buffer attached to the window. + + Buffer scale is double-buffered state, see :func:`WlSurface.commit()`. + + A newly created surface has its buffer scale set to 1. + + :func:`WlSurface.set_buffer_scale()` changes the pending buffer scale. + :func:`WlSurface.commit()` copies the pending buffer scale to the + current one. Otherwise, the pending and current values are never + changed. + + The purpose of this request is to allow clients to supply higher + resolution buffer data for use on high resolution outputs. It is + intended that you pick the same buffer scale as the scale of the output + that the surface is displayed on. This means the compositor can avoid + scaling when rendering the surface on that output. + + Note that if the scale is larger than 1, then you have to attach a + buffer that is larger (by a factor of scale in each dimension) than the + desired surface size. + + If scale is not positive the invalid_scale protocol error is raised. + + :param scale: + positive scale for interpreting buffer contents + :type scale: + `ArgumentType.Int` + """ + self._marshal(8, scale) + + @WlSurface.request( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + version=4, + ) + def damage_buffer(self, x: int, y: int, width: int, height: int) -> None: + """Mark part of the surface damaged using buffer coordinates + + This request is used to describe the regions where the pending buffer + is different from the current surface contents, and where the surface + therefore needs to be repainted. The compositor ignores the parts of + the damage that fall outside of the surface. + + Damage is double-buffered state, see :func:`WlSurface.commit()`. + + The damage rectangle is specified in buffer coordinates, where x and y + specify the upper left corner of the damage rectangle. + + The initial value for pending damage is empty: no damage. + :func:`WlSurface.damage_buffer()` adds pending damage: the new pending + damage is the union of old pending damage and the given rectangle. + + :func:`WlSurface.commit()` assigns pending damage as the current + damage, and clears pending damage. The server will clear the current + damage as it repaints the surface. + + This request differs from :func:`WlSurface.damage()` in only one way - + it takes damage in buffer coordinates instead of surface-local + coordinates. While this generally is more intuitive than surface + coordinates, it is especially desirable when using wp_viewport or when + a drawing library (like EGL) is unaware of buffer scale and buffer + transform. + + Note: Because buffer transformation changes and damage requests may be + interleaved in the protocol stream, it is impossible to determine the + actual mapping between surface and buffer damage until + :func:`WlSurface.commit()` time. Therefore, compositors wishing to take + both kinds of damage into account will have to accumulate damage from + the two requests separately and only transform from one to the other + after receiving the :func:`WlSurface.commit()`. + + :param x: + buffer-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + buffer-local y coordinate + :type y: + `ArgumentType.Int` + :param width: + width of damage rectangle + :type width: + `ArgumentType.Int` + :param height: + height of damage rectangle + :type height: + `ArgumentType.Int` + """ + self._marshal(9, x, y, width, height) + + @WlSurface.request( + Argument(ArgumentType.Int), + Argument(ArgumentType.Int), + version=5, + ) + def offset(self, x: int, y: int) -> None: + """Set the surface contents offset + + The x and y arguments specify the location of the new pending buffer's + upper left corner, relative to the current buffer's upper left corner, + in surface-local coordinates. In other words, the x and y, combined + with the new surface size define in which directions the surface's size + changes. + + Surface location offset is double-buffered state, see + :func:`WlSurface.commit()`. + + This request is semantically equivalent to and the replaces the x and y + arguments in the :func:`WlSurface.attach()` request in + :class:`WlSurface` versions prior to 5. See :func:`WlSurface.attach()` + for details. + + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Int` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Int` + """ + self._marshal(10, x, y) + + +class WlSurfaceResource(Resource): + interface = WlSurface + + @WlSurface.event( + Argument(ArgumentType.Object, interface=WlOutput), + ) + def enter(self, output: WlOutput) -> None: + """Surface enters an output + + This is emitted whenever a surface's creation, movement, or resizing + results in some part of it being within the scanout region of an + output. + + Note that a surface may be overlapping with zero or more outputs. + + :param output: + output entered by the surface + :type output: + :class:`~pywayland.protocol.wayland.WlOutput` + """ + self._post_event(0, output) + + @WlSurface.event( + Argument(ArgumentType.Object, interface=WlOutput), + ) + def leave(self, output: WlOutput) -> None: + """Surface leaves an output + + This is emitted whenever a surface's creation, movement, or resizing + results in it no longer having any part of it within the scanout region + of an output. + + Clients should not use the number of outputs the surface is on for + frame throttling purposes. The surface might be hidden even if no leave + event has been sent, and the compositor might expect new surface + content updates even if no enter event has been sent. The frame event + should be used instead. + + :param output: + output left by the surface + :type output: + :class:`~pywayland.protocol.wayland.WlOutput` + """ + self._post_event(1, output) + + @WlSurface.event( + Argument(ArgumentType.Int), + version=6, + ) + def preferred_buffer_scale(self, factor: int) -> None: + """Preferred buffer scale for the surface + + This event indicates the preferred buffer scale for this surface. It is + sent whenever the compositor's preference changes. + + It is intended that scaling aware clients use this event to scale their + content and use :func:`WlSurface.set_buffer_scale()` to indicate the + scale they have rendered with. This allows clients to supply a higher + detail buffer. + + :param factor: + preferred scaling factor + :type factor: + `ArgumentType.Int` + """ + self._post_event(2, factor) + + @WlSurface.event( + Argument(ArgumentType.Uint), + version=6, + ) + def preferred_buffer_transform(self, transform: int) -> None: + """Preferred buffer transform for the surface + + This event indicates the preferred buffer transform for this surface. + It is sent whenever the compositor's preference changes. + + It is intended that transform aware clients use this event to apply the + transform to their content and use + :func:`WlSurface.set_buffer_transform()` to indicate the transform they + have rendered with. + + :param transform: + preferred transform + :type transform: + `ArgumentType.Uint` + """ + self._post_event(3, transform) + + +class WlSurfaceGlobal(Global): + interface = WlSurface + + +WlSurface._gen_c() +WlSurface.proxy_class = WlSurfaceProxy +WlSurface.resource_class = WlSurfaceResource +WlSurface.global_class = WlSurfaceGlobal diff --git a/bar/generated/wayland/wl_touch.py b/bar/generated/wayland/wl_touch.py new file mode 100644 index 0000000..38b8d1b --- /dev/null +++ b/bar/generated/wayland/wl_touch.py @@ -0,0 +1,304 @@ +# This file has been autogenerated by the pywayland scanner + +# Copyright © 2008-2011 Kristian Høgsberg +# Copyright © 2010-2011 Intel Corporation +# Copyright © 2012-2013 Collabora, Ltd. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial +# portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import annotations + +from pywayland.protocol_core import ( + Argument, + ArgumentType, + Global, + Interface, + Proxy, + Resource, +) + +from .wl_surface import WlSurface + + +class WlTouch(Interface): + """Touchscreen input device + + The :class:`WlTouch` interface represents a touchscreen associated with a + seat. + + Touch interactions can consist of one or more contacts. For each contact, a + series of events is generated, starting with a down event, followed by zero + or more motion events, and ending with an up event. Events relating to the + same contact point can be identified by the ID of the sequence. + """ + + name = "wl_touch" + version = 9 + + +class WlTouchProxy(Proxy[WlTouch]): + interface = WlTouch + + @WlTouch.request(version=3) + def release(self) -> None: + """Release the touch object + """ + self._marshal(0) + self._destroy() + + +class WlTouchResource(Resource): + interface = WlTouch + + @WlTouch.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Object, interface=WlSurface), + Argument(ArgumentType.Int), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Fixed), + ) + def down(self, serial: int, time: int, surface: WlSurface, id: int, x: float, y: float) -> None: + """Touch down event and beginning of a touch sequence + + A new touch point has appeared on the surface. This touch point is + assigned a unique ID. Future events from this touch point reference + this ID. The ID ceases to be valid after a touch up event and may be + reused in the future. + + :param serial: + serial number of the touch down event + :type serial: + `ArgumentType.Uint` + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param surface: + surface touched + :type surface: + :class:`~pywayland.protocol.wayland.WlSurface` + :param id: + the unique ID of this touch point + :type id: + `ArgumentType.Int` + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Fixed` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Fixed` + """ + self._post_event(0, serial, time, surface, id, x, y) + + @WlTouch.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Uint), + Argument(ArgumentType.Int), + ) + def up(self, serial: int, time: int, id: int) -> None: + """End of a touch event sequence + + The touch point has disappeared. No further events will be sent for + this touch point and the touch point's ID is released and may be reused + in a future touch down event. + + :param serial: + serial number of the touch up event + :type serial: + `ArgumentType.Uint` + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param id: + the unique ID of this touch point + :type id: + `ArgumentType.Int` + """ + self._post_event(1, serial, time, id) + + @WlTouch.event( + Argument(ArgumentType.Uint), + Argument(ArgumentType.Int), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Fixed), + ) + def motion(self, time: int, id: int, x: float, y: float) -> None: + """Update of touch point coordinates + + A touch point has changed coordinates. + + :param time: + timestamp with millisecond granularity + :type time: + `ArgumentType.Uint` + :param id: + the unique ID of this touch point + :type id: + `ArgumentType.Int` + :param x: + surface-local x coordinate + :type x: + `ArgumentType.Fixed` + :param y: + surface-local y coordinate + :type y: + `ArgumentType.Fixed` + """ + self._post_event(2, time, id, x, y) + + @WlTouch.event() + def frame(self) -> None: + """End of touch frame event + + Indicates the end of a set of events that logically belong together. A + client is expected to accumulate the data in all events within the + frame before proceeding. + + A :func:`WlTouch.frame()` terminates at least one event but otherwise + no guarantee is provided about the set of events within a frame. A + client must assume that any state not updated in a frame is unchanged + from the previously known state. + """ + self._post_event(3) + + @WlTouch.event() + def cancel(self) -> None: + """Touch session cancelled + + Sent if the compositor decides the touch stream is a global gesture. No + further events are sent to the clients from that particular gesture. + Touch cancellation applies to all touch points currently active on this + client's surface. The client is responsible for finalizing the touch + points, future touch points on this surface may reuse the touch point + ID. + """ + self._post_event(4) + + @WlTouch.event( + Argument(ArgumentType.Int), + Argument(ArgumentType.Fixed), + Argument(ArgumentType.Fixed), + version=6, + ) + def shape(self, id: int, major: float, minor: float) -> None: + """Update shape of touch point + + Sent when a touchpoint has changed its shape. + + This event does not occur on its own. It is sent before a + :func:`WlTouch.frame()` event and carries the new shape information for + any previously reported, or new touch points of that frame. + + Other events describing the touch point such as :func:`WlTouch.down()`, + :func:`WlTouch.motion()` or :func:`WlTouch.orientation()` may be sent + within the same :func:`WlTouch.frame()`. A client should treat these + events as a single logical touch point update. The order of + :func:`WlTouch.shape()`, :func:`WlTouch.orientation()` and + :func:`WlTouch.motion()` is not guaranteed. A :func:`WlTouch.down()` + event is guaranteed to occur before the first :func:`WlTouch.shape()` + event for this touch ID but both events may occur within the same + :func:`WlTouch.frame()`. + + A touchpoint shape is approximated by an ellipse through the major and + minor axis length. The major axis length describes the longer diameter + of the ellipse, while the minor axis length describes the shorter + diameter. Major and minor are orthogonal and both are specified in + surface-local coordinates. The center of the ellipse is always at the + touchpoint location as reported by :func:`WlTouch.down()` or + :func:`WlTouch.move()`. + + This event is only sent by the compositor if the touch device supports + shape reports. The client has to make reasonable assumptions about the + shape if it did not receive this event. + + :param id: + the unique ID of this touch point + :type id: + `ArgumentType.Int` + :param major: + length of the major axis in surface-local coordinates + :type major: + `ArgumentType.Fixed` + :param minor: + length of the minor axis in surface-local coordinates + :type minor: + `ArgumentType.Fixed` + """ + self._post_event(5, id, major, minor) + + @WlTouch.event( + Argument(ArgumentType.Int), + Argument(ArgumentType.Fixed), + version=6, + ) + def orientation(self, id: int, orientation: float) -> None: + """Update orientation of touch point + + Sent when a touchpoint has changed its orientation. + + This event does not occur on its own. It is sent before a + :func:`WlTouch.frame()` event and carries the new shape information for + any previously reported, or new touch points of that frame. + + Other events describing the touch point such as :func:`WlTouch.down()`, + :func:`WlTouch.motion()` or :func:`WlTouch.shape()` may be sent within + the same :func:`WlTouch.frame()`. A client should treat these events as + a single logical touch point update. The order of + :func:`WlTouch.shape()`, :func:`WlTouch.orientation()` and + :func:`WlTouch.motion()` is not guaranteed. A :func:`WlTouch.down()` + event is guaranteed to occur before the first + :func:`WlTouch.orientation()` event for this touch ID but both events + may occur within the same :func:`WlTouch.frame()`. + + The orientation describes the clockwise angle of a touchpoint's major + axis to the positive surface y-axis and is normalized to the -180 to + +180 degree range. The granularity of orientation depends on the touch + device, some devices only support binary rotation values between 0 and + 90 degrees. + + This event is only sent by the compositor if the touch device supports + orientation reports. + + :param id: + the unique ID of this touch point + :type id: + `ArgumentType.Int` + :param orientation: + angle between major axis and positive surface y-axis in degrees + :type orientation: + `ArgumentType.Fixed` + """ + self._post_event(6, id, orientation) + + +class WlTouchGlobal(Global): + interface = WlTouch + + +WlTouch._gen_c() +WlTouch.proxy_class = WlTouchProxy +WlTouch.resource_class = WlTouchResource +WlTouch.global_class = WlTouchGlobal diff --git a/bar/river/__init__.py b/bar/river/__init__.py new file mode 100644 index 0000000..ec4daab --- /dev/null +++ b/bar/river/__init__.py @@ -0,0 +1,3 @@ +from .service import River + +__all__ = ["River"] diff --git a/bar/river/protocol/river-control-unstable-v1.xml b/bar/river/protocol/river-control-unstable-v1.xml new file mode 100644 index 0000000..aa5fc4d --- /dev/null +++ b/bar/river/protocol/river-control-unstable-v1.xml @@ -0,0 +1,85 @@ + + + + Copyright 2020 The River Developers + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + + + + This interface allows clients to run compositor commands and receive a + success/failure response with output or a failure message respectively. + + Each command is built up in a series of add_argument requests and + executed with a run_command request. The first argument is the command + to be run. + + A complete list of commands should be made available in the man page of + the compositor. + + + + + This request indicates that the client will not use the + river_control object any more. Objects that have been created + through this instance are not affected. + + + + + + Arguments are stored by the server in the order they were sent until + the run_command request is made. + + + + + + + Execute the command built up using the add_argument request for the + given seat. + + + + + + + + + This object is created by the run_command request. Exactly one of the + success or failure events will be sent. This object will be destroyed + by the compositor after one of the events is sent. + + + + + Sent when the command has been successfully received and executed by + the compositor. Some commands may produce output, in which case the + output argument will be a non-empty string. + + + + + + + Sent when the command could not be carried out. This could be due to + sending a non-existent command, no command, not enough arguments, too + many arguments, invalid arguments, etc. + + + + + diff --git a/bar/river/protocol/river-status-unstable-v1.xml b/bar/river/protocol/river-status-unstable-v1.xml new file mode 100644 index 0000000..e9629dd --- /dev/null +++ b/bar/river/protocol/river-status-unstable-v1.xml @@ -0,0 +1,148 @@ + + + + Copyright 2020 The River Developers + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + + + + A global factory for objects that receive status information specific + to river. It could be used to implement, for example, a status bar. + + + + + This request indicates that the client will not use the + river_status_manager object any more. Objects that have been created + through this instance are not affected. + + + + + + This creates a new river_output_status object for the given wl_output. + + + + + + + + This creates a new river_seat_status object for the given wl_seat. + + + + + + + + + This interface allows clients to receive information about the current + windowing state of an output. + + + + + This request indicates that the client will not use the + river_output_status object any more. + + + + + + Sent once binding the interface and again whenever the tag focus of + the output changes. + + + + + + + Sent once on binding the interface and again whenever the tag state + of the output changes. + + + + + + + Sent once on binding the interface and again whenever the set of + tags with at least one urgent view changes. + + + + + + + Sent once on binding the interface should a layout name exist and again + whenever the name changes. + + + + + + + Sent when the current layout name has been removed without a new one + being set, for example when the active layout generator disconnects. + + + + + + + This interface allows clients to receive information about the current + focus of a seat. Note that (un)focused_output events will only be sent + if the client has bound the relevant wl_output globals. + + + + + This request indicates that the client will not use the + river_seat_status object any more. + + + + + + Sent on binding the interface and again whenever an output gains focus. + + + + + + + Sent whenever an output loses focus. + + + + + + + Sent once on binding the interface and again whenever the focused + view or a property thereof changes. The title may be an empty string + if no view is focused or the focused view did not set a title. + + + + + + + Sent once on binding the interface and again whenever a new mode + is entered (e.g. with riverctl enter-mode foobar). + + + + + diff --git a/bar/river/service.py b/bar/river/service.py new file mode 100644 index 0000000..333a8ab --- /dev/null +++ b/bar/river/service.py @@ -0,0 +1,117 @@ +import logging +from dataclasses import dataclass, field +from typing import Dict, List + +from fabric.core.service import Service, Signal, Property +from pywayland.client import Display +from pywayland.protocol.wayland import WlOutput, WlSeat +from ..generated.river_status_unstable_v1 import ( + ZriverStatusManagerV1, + ZriverOutputStatusV1, + ZriverSeatStatusV1, +) + +logger = logging.getLogger(__name__) + + +@dataclass +class OutputState: + id: int + output: WlOutput + status: ZriverOutputStatusV1 = None + focused_tags: List[int] = field(default_factory=list) + view_tags: List[int] = field(default_factory=list) + + +class River(Service): + @Property(bool, "readable", "is-ready", default_value=False) + def ready(self) -> bool: + return self._ready + + @Signal + def ready(self): + return self.notify("ready") + + @Signal("event", flags="detailed") + def event(self, event: object): ... + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self._ready = False + self.display = None + self.registry = None + self.outputs: Dict[int, OutputState] = {} + self.status_mgr = None + self.seat = None + self.seat_status: ZriverSeatStatusV1 = None + self.ready.emit() + + def on_start(self): + print("✅ River.on_start called") + + logger.info("[RiverService] Starting River service...") + self.display = Display() + self.display.connect() + self.registry = self.display.get_registry() + + self.registry.dispatcher["global"] = self._on_global + self.registry.dispatcher["global_remove"] = lambda *_: None + + self.display.roundtrip() + + if self.seat and self.status_mgr: + self.seat_status = self.status_mgr.get_river_seat_status(self.seat) + + for id, output_state in self.outputs.items(): + status = self.status_mgr.get_river_output_status(output_state.output) + output_state.status = status + status.dispatcher["focused_tags"] = self._make_focused_handler(id) + status.dispatcher["view_tags"] = self._make_view_handler(id) + + self.display.roundtrip() + + self._ready = True + self.ready.emit() + logger.info("[RiverService] Ready. Monitoring tags.") + + def on_tick(self): + # Periodic poll + self.display.roundtrip() + + def _on_global(self, registry, name, interface, version): + if interface == "wl_output": + output = registry.bind(name, WlOutput, version) + self.outputs[name] = OutputState(id=name, output=output) + + elif interface == "wl_seat": + self.seat = registry.bind(name, WlSeat, version) + + elif interface == "zriver_status_manager_v1": + self.status_mgr = registry.bind(name, ZriverStatusManagerV1, version) + + def _make_focused_handler(self, output_id): + def handler(_, bitfield): + tags = self._decode_bitfield(bitfield) + self.outputs[output_id].focused_tags = tags + logger.debug(f"[RiverService] Output {output_id} focused: {tags}") + self.emit(f"event::focused_tags::{output_id}", tags) + + return handler + + def _make_view_handler(self, output_id): + def handler(_, array): + tags = self._decode_array_bitfields(array) + self.outputs[output_id].view_tags = tags + logger.debug(f"[RiverService] Output {output_id} views: {tags}") + self.emit(f"event::view_tags::{output_id}", tags) + + return handler + + def _decode_bitfield(self, bits: int) -> List[int]: + return [i for i in range(32) if bits & (1 << i)] + + def _decode_array_bitfields(self, array) -> List[int]: + tags = set() + for bits in array: + tags.update(self._decode_bitfield(bits)) + return sorted(tags) diff --git a/bar/river/widgets.py b/bar/river/widgets.py new file mode 100644 index 0000000..0d01481 --- /dev/null +++ b/bar/river/widgets.py @@ -0,0 +1,99 @@ +from fabric.core.service import Property +from fabric.widgets.button import Button +from fabric.widgets.box import Box +from fabric.widgets.eventbox import EventBox +from fabric.utils.helpers import bulk_connect +from .service import River + + +from gi.repository import Gdk + +_connection: River | None = None + + +def get_river_connection() -> River: + global _connection + if not _connection: + _connection = River() + return _connection + + +class RiverWorkspaceButton(Button): + @Property(int, "readable") + def id(self) -> int: + return self._id + + @Property(bool, "read-write", default_value=False) + def active(self) -> bool: + return self._active + + @active.setter + def active(self, value: bool): + self._active = value + (self.remove_style_class if not value else self.add_style_class)("active") + + @Property(bool, "read-write", default_value=False) + def empty(self) -> bool: + return self._empty + + @empty.setter + def empty(self, value: bool): + self._empty = value + (self.remove_style_class if not value else self.add_style_class)("empty") + + def __init__(self, id: int, label: str = None, **kwargs): + super().__init__(label or str(id), **kwargs) + self._id = id + self._active = False + self._empty = True + + +class RiverWorkspaces(EventBox): + def __init__(self, output_id: int, max_tags: int = 9, **kwargs): + super().__init__(events="scroll") + self.output_id = output_id + self.max_tags = max_tags + self.service = get_river_connection() + self._box = Box(**kwargs) + self.children = self._box + + self._buttons = {i: RiverWorkspaceButton(i) for i in range(max_tags)} + for btn in self._buttons.values(): + btn.connect("clicked", self.on_workspace_click) + self._box.add(btn) + + # hook into River signals + self.service.connect(f"event::focused_tags::{output_id}", self.on_focus_change) + self.service.connect(f"event::view_tags::{output_id}", self.on_view_change) + if self.service.ready: + self.on_ready(None) + else: + self.service.connect("event::ready", self.on_ready) + + self.connect("scroll-event", self.on_scroll) + + def on_ready(self, _): + print(self.service.outputs) + + def on_focus_change(self, _, tags: list[int]): + print(tags) + for i, btn in self._buttons.items(): + btn.active = i in tags + + def on_view_change(self, _, tags: list[int]): + print(tags) + for i, btn in self._buttons.items(): + btn.empty = i not in tags + + def on_workspace_click(self, btn: RiverWorkspaceButton): + import subprocess + + subprocess.run(["riverctl", "tag", str(btn.id)]) + return + + def on_scroll(self, _, event: Gdk.EventScroll): + direction = event.direction # UP or DOWN + cmd = "tag +1" if direction == Gdk.ScrollDirection.DOWN else "tag -1" + import subprocess + + subprocess.run(["riverctl", *cmd.split()]) diff --git a/bar/test.py b/bar/test.py new file mode 100644 index 0000000..8c2c620 --- /dev/null +++ b/bar/test.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Callable +from pywayland.client import Display +from pywayland.protocol.wayland import WlOutput, WlRegistry, WlSeat +from .generated.river_status_unstable_v1 import ( + ZriverStatusManagerV1, + ZriverOutputStatusV1, +) + + +@dataclass +class OutputInfo: + name: int + output: WlOutput + status: ZriverOutputStatusV1 + tags_view: list[int] = field(default_factory=list) + tags_focused: list[int] = field(default_factory=list) + + +@dataclass +class State: + display: Display + registry: WlRegistry + outputs: dict[int, OutputInfo] = field(default_factory=dict) + river_status_mgr: ZriverStatusManagerV1 | None = None + seat: WlSeat | None = None + seat_status: ZriverSeatStatusV1 | None = None + + +def decode_bitfields(bitfields: list[int] | int) -> list[int]: + tags = set() + if isinstance(bitfields, int): + bitfields = [bitfields] + for bits in bitfields: + for i in range(32): + if bits & (1 << i): + tags.add(i) + return sorted(tags) + + +def handle_global( + state: State, registry: WlRegistry, name: int, iface: str, version: int +) -> None: + if iface == "zriver_status_manager_v1": + state.river_status_mgr = registry.bind(name, ZriverStatusManagerV1, version) + + elif iface == "wl_output": + output = registry.bind(name, WlOutput, version) + state.outputs[name] = OutputInfo(name=name, output=output, status=None) + elif iface == "wl_seat": + seat = registry.bind(name, WlSeat, version) + state.seat = seat + + +def handle_global_remove(state: State, registry: WlRegistry, name: int) -> None: + if name in state.outputs: + print(f"Output {name} removed.") + del state.outputs[name] + + +def make_view_tags_handler(state: State, name: int) -> Callable: + def handler(self, tags: list[int]) -> None: + decoded = decode_bitfields(tags) + state.outputs[name].tags_view = decoded + print(f"[Output {name}] View tags: {decoded}") + + return handler + + +def make_focused_tags_handler(state: State, name: int) -> Callable: + def handler(self, tags: int) -> None: + decoded = decode_bitfields(tags) + state.outputs[name].tags_focused = decoded + print(f"[Output {name}] Focused tags: {decoded}") + + return handler + + +def main() -> None: + with Display() as display: + registry = display.get_registry() + state = State(display=display, registry=registry) + + registry.dispatcher["global"] = lambda reg, name, iface, ver: handle_global( + state, reg, name, iface, ver + ) + registry.dispatcher["global_remove"] = lambda reg, name: handle_global_remove( + state, reg, name + ) + + # Discover globals + display.roundtrip() + + if not state.river_status_mgr: + print("❌ River status manager not found.") + return + + # Bind output status listeners + for name, info in state.outputs.items(): + status = state.river_status_mgr.get_river_output_status(info.output) + status.dispatcher["view_tags"] = make_view_tags_handler(state, name) + status.dispatcher["focused_tags"] = make_focused_tags_handler(state, name) + info.status = status + + if state.seat: + state.seat_status = state.river_status_mgr.get_river_seat_status(state.seat) + print("✅ Bound seat status") + + # Initial data + display.roundtrip() + + print("🟢 Listening for tag changes. Press Ctrl+C to exit.") + while True: + display.roundtrip() + + +if __name__ == "__main__": + main() diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..6513df0 --- /dev/null +++ b/default.nix @@ -0,0 +1,5 @@ +{ + pkgs ? import { }, +}: + +pkgs.callPackage ./derivation.nix { } diff --git a/derivation.nix b/derivation.nix new file mode 100644 index 0000000..7e76e6f --- /dev/null +++ b/derivation.nix @@ -0,0 +1,56 @@ +{ + lib, + python3Packages, + gtk3, + gtk-layer-shell, + cairo, + gobject-introspection, + libdbusmenu-gtk3, + gdk-pixbuf, + gnome, + cinnamon, + wrapGAppsHook3, + ... +}: + +python3Packages.buildPythonApplication { + pname = "fabric-nix-example"; + version = "0.0.1"; + pyproject = true; + + src = ./.; + + nativeBuildInputs = [ + wrapGAppsHook3 + gtk3 + gobject-introspection + cairo + ]; + # buildInputs = [ + # libdbusmenu-gtk3 + # gtk-layer-shell + # gnome.gnome-bluetooth + # cinnamon.cinnamon-desktop + # gdk-pixbuf + # ]; + + dependencies = with python3Packages; [ + python-fabric + pywayland + ]; + doCheck = false; + dontWrapGApps = true; + + preFixup = '' + makeWrapperArgs+=("''${gappsWrapperArgs[@]}") + ''; + + meta = { + changelog = ""; + description = '' + Fabrix Bar Example + ''; + homepage = "https://github.com/wholikeel/fabric"; + license = lib.licenses.agpl3Only; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..1018f48 --- /dev/null +++ b/flake.lock @@ -0,0 +1,147 @@ +{ + "nodes": { + "fabric": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + }, + "locked": { + "lastModified": 1725442219, + "narHash": "sha256-xgTjqwlAgfY0Kv6G6CogOV2pN6U0wllRYteVAAZs7BU=", + "owner": "wholikeel", + "repo": "fabric-nix", + "rev": "3bc86cfb8c988ff5488526a47e1914f03a34a87c", + "type": "github" + }, + "original": { + "owner": "wholikeel", + "repo": "fabric-nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1717179513, + "narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1717179513, + "narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "fabric": "fabric", + "nixpkgs": "nixpkgs_2", + "unstable": "unstable", + "utils": "utils_2" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "unstable": { + "locked": { + "lastModified": 1745930157, + "narHash": "sha256-y3h3NLnzRSiUkYpnfvnS669zWZLoqqI6NprtLQ+5dck=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "46e634be05ce9dc6d4db8e664515ba10b78151ae", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..28b7d37 --- /dev/null +++ b/flake.nix @@ -0,0 +1,40 @@ +{ + description = "Fabric Bar Example"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/24.05"; + unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; + utils.url = "github:numtide/flake-utils"; + fabric.url = "github:wholikeel/fabric-nix"; + }; + + outputs = + { + self, + nixpkgs, + unstable, + utils, + fabric, + ... + }: + utils.lib.eachDefaultSystem ( + system: + let + # Dependencies want from nixpkgs unstable as an overlay + unstable-overlay = final: prev: { basedpyright = unstable.legacyPackages.${system}.basedpyright; }; + # Fabric overlay + fabric-overlay = fabric.overlays.${system}.default; + # Apply both overlays + pkgs = (nixpkgs.legacyPackages.${system}.extend fabric-overlay).extend unstable-overlay; + in + { + formatter = pkgs.nixfmt-rfc-style; + devShells.default = pkgs.callPackage ./shell.nix { inherit pkgs; }; + packages.default = pkgs.callPackage ./derivation.nix { inherit (pkgs) lib python3Packages; }; + apps.default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/bar"; + }; + } + ); +} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..bfe38a3 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "fabric-nix-example" +version = "0.0.1" +requires-python = ">= 3.11" +authors = [ +] +maintainers = [ +] +description = "Fabric using Nix example." +readme = "README.md" +license = {file = "LICENSE"} + +[project.scripts] +bar = "bar.bar:main" + +[tool.setuptools.packages.find] +where = ["."] + +[tool.setuptools.package-data] +bar = ["bar.css"] diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..b9fbe22 --- /dev/null +++ b/shell.nix @@ -0,0 +1,45 @@ +{ + pkgs ? import { }, +}: +pkgs.mkShell { + name = "fabric-shell"; + buildInputs = with pkgs; [ + dbus + wayland-scanner + ]; + nativeBuildInputs = with pkgs; [ + pkg-config + ]; + dbus = pkgs.dbus; + packages = with pkgs; [ + ruff # Linter + basedpyright # Language server + + # Required for Devshell + gtk3 + gtk-layer-shell + cairo + gobject-introspection + libdbusmenu-gtk3 + gdk-pixbuf + gnome.gnome-bluetooth + cinnamon.cinnamon-desktop + wayland-scanner + wayland + wayland-protocols + (python3.withPackages ( + ps: with ps; [ + setuptools + wheel + build + python-fabric + psutil + pywayland + python-lsp-server + pylsp-mypy + pyls-isort + python-lsp-ruff + ] + )) + ]; +}