128 lines
4.8 KiB
Python
128 lines
4.8 KiB
Python
from sdbus import (
|
|
DbusInterfaceCommonAsync,
|
|
dbus_method_async,
|
|
dbus_property_async,
|
|
dbus_signal_async,
|
|
)
|
|
import os
|
|
from .workspace_tree import WorkspaceTree
|
|
from i3ipc.aio import Connection
|
|
import json
|
|
|
|
|
|
class ContextMngrInterface(
|
|
DbusInterfaceCommonAsync,
|
|
interface_name="dev.ezri.sway.ContextManager",
|
|
):
|
|
|
|
workspace_tree: WorkspaceTree = None
|
|
connection: Connection = None
|
|
|
|
def __init__(
|
|
self, workspace_tree: WorkspaceTree, connection: Connection, *args, **kwargs
|
|
):
|
|
super().__init__(*args, **kwargs)
|
|
self.workspace_tree = workspace_tree
|
|
self.connection = connection
|
|
|
|
@dbus_method_async(input_signature="s", result_signature="s")
|
|
async def request_context(self, context: str) -> str:
|
|
"""Request a context switch. This will fail if the current monitor configuration is not compatible with the requested context."""
|
|
print("requesting context", context)
|
|
try:
|
|
await self.workspace_tree.activate_context(self.connection, context)
|
|
return "OK"
|
|
except Exception as e:
|
|
return str(e)
|
|
|
|
@dbus_method_async(input_signature="", result_signature="s")
|
|
async def get_current_context(self) -> str:
|
|
"""Get the current context."""
|
|
return self.workspace_tree.current_context.name
|
|
|
|
@dbus_method_async(input_signature="y", result_signature="b")
|
|
async def focus_workspace(self, user_index: int) -> bool:
|
|
"""Focus a workspace by its 1-indexed ID in its group."""
|
|
print("focusing workspace", user_index)
|
|
workspace, group = self.workspace_tree.get_workspace(user_index)
|
|
if workspace is None or group is None:
|
|
return False
|
|
await workspace.relocate(
|
|
self.connection, await group.get_output_name(self.connection)
|
|
)
|
|
return True
|
|
|
|
@dbus_method_async(input_signature="y", result_signature="b")
|
|
async def move_container(self, user_index: int) -> bool:
|
|
"""Move the focused container to a workspace by its 1-indexed ID in its group."""
|
|
print("Moving focused container to workspace", user_index)
|
|
workspace, _ = self.workspace_tree.get_workspace(user_index)
|
|
if workspace is None:
|
|
return False
|
|
await workspace[0].move_container(self.connection)
|
|
return True
|
|
|
|
@dbus_method_async(input_signature="", result_signature="b")
|
|
async def launch_default(self) -> bool:
|
|
"""Launch the default application for the current workspace."""
|
|
print("launching default")
|
|
await self.workspace_tree.current_context.active_workspace.launch_default(
|
|
self.connection
|
|
)
|
|
return True
|
|
|
|
@dbus_method_async(input_signature="y", result_signature="s")
|
|
async def get_workspace(self, user_index: int) -> bool:
|
|
"""Get a workspace by its 1-indexed ID in its group."""
|
|
workspace = self.workspace_tree.get_workspace(user_index)
|
|
if workspace is None:
|
|
return ""
|
|
return json.dumps(workspace.__json__())
|
|
|
|
async def __get_workspace_data(self) -> dict:
|
|
"""Get the workspace tree."""
|
|
try:
|
|
active = self.workspace_tree.current_context.active_workspace
|
|
return {
|
|
"ws": self.workspace_tree.__json__(),
|
|
"current": active is not None and active.__json__() or None,
|
|
"context": self.workspace_tree.current_context.name,
|
|
"visible": {
|
|
name: ws is not None
|
|
and ws.__json__()
|
|
or {
|
|
"name": f"<undefined:{name}>",
|
|
"index": -1,
|
|
"active": True,
|
|
"visible": True,
|
|
"focused": False,
|
|
"alerted": False,
|
|
}
|
|
for name, ws in self.workspace_tree.current_context.visible_workspaces.items()
|
|
},
|
|
}
|
|
except Exception as e:
|
|
print(e)
|
|
return {}
|
|
|
|
@dbus_method_async(input_signature="", result_signature="s")
|
|
async def get_workspace_data(self) -> str:
|
|
"""Get the workspace tree."""
|
|
data = await self.__get_workspace_data()
|
|
return json.dumps(data)
|
|
|
|
@dbus_method_async(input_signature="", result_signature="s")
|
|
async def get_workspace_definition(self) -> str:
|
|
"""Get the definition of the currently focused workspace."""
|
|
workspace = self.workspace_tree.current_context.active_workspace
|
|
return json.dumps(workspace.definition)
|
|
|
|
@dbus_signal_async("s")
|
|
async def tree_changed(self):
|
|
"""Signal emitted when the workspace tree changes."""
|
|
raise NotImplementedError
|
|
|
|
async def on_tree_changed(self, workspace_tree: str):
|
|
print("tree changed, emitting signal")
|
|
self.tree_changed.emit(json.dumps(await self.__get_workspace_data()))
|