Skip to content

Commit

Permalink
feat: Port from qdbus to gdbus command
Browse files Browse the repository at this point in the history
--qdbus-executable (qdbus_executable in config) is now deprecated

closes: #224
  • Loading branch information
luisbocanegra committed Nov 5, 2024
1 parent e3e2904 commit 19597f6
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 162 deletions.
11 changes: 2 additions & 9 deletions src/kde_material_you_colors/apply_themes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@

def apply(config: Configs, wallpaper: WallpaperReader, dark_light):
needs_kwin_reload = False
qdbus_executable = config.read("qdbus_executable")
if qdbus_executable is None:
qdbus_executable = "qdbus6"
if utils.find_executable(qdbus_executable) is None:
logging.error(
f"QDbus executable '{qdbus_executable}' wasn't found, there will be errors. Please set the correct one in the configuration"
)

material_colors = m3_scheme_utils.get_color_schemes(
wallpaper,
Expand Down Expand Up @@ -80,7 +73,7 @@ def apply(config: Configs, wallpaper: WallpaperReader, dark_light):
dark_light=dark_light,
)
if config.read("disable_konsole") is not True:
konsole_utils.apply_color_scheme(qdbus_executable)
konsole_utils.apply_color_scheme()
if config.read("darker_window_list"):
titlebar_utils.kwin_rule_darker_titlebar(
(
Expand All @@ -99,7 +92,7 @@ def apply(config: Configs, wallpaper: WallpaperReader, dark_light):
dark_light=dark_light,
)
if needs_kwin_reload is True:
kwin_utils.reload(qdbus_executable)
kwin_utils.reload()
pywal_utils.print_color_palette(
light=config.read("light"),
pywal_light=config.read("pywal_light"),
Expand Down
5 changes: 5 additions & 0 deletions src/kde_material_you_colors/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ def update_config(self):
f"Value for main_loop_delay ({options['main_loop_delay']}) should be smaller than screenshot_delay ({options['screenshot_delay']}), will be set to {options['screenshot_delay']}"
)

if options["qdbus_executable"] is not None:
logging.warning(
"--qdbus-executable (qdbus_executable in config) is deprecated as of version 1.10.0 and will be removed in a later version"
)

self._options = options

@property
Expand Down
3 changes: 2 additions & 1 deletion src/kde_material_you_colors/data/sample_config.conf
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,5 @@ tone_multiplier = 1
# QDbus executable
# Name or location of the QDbus executable e.g qdbus6, qdbus-qt6...
# Default is qdbus6
#qdbus_executable = qdbus6
# Deprecated, no longer needed as of version 1.10.0. Switched to gdbus command from glib2
# qdbus_executable = qdbus6
2 changes: 1 addition & 1 deletion src/kde_material_you_colors/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def main():
parser.add_argument(
"--qdbus-executable",
type=str,
help="Name or location of the QDbus executable e.g qdbus6, qdbus-qt6... (default is qdbus6)",
help="(Deprecated as of version 1.10.0) Name or location of the QDbus executable e.g qdbus6, qdbus-qt6... (default is qdbus6)",
default=None,
metavar="<string>",
)
Expand Down
53 changes: 53 additions & 0 deletions src/kde_material_you_colors/utils/dbus_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from xml.etree import ElementTree
import dbus


def list_paths(
bus: dbus.Bus,
service: str,
search_path: str = "/",
current_path: str = "",
paths=None,
):
"""List the paths from a dbus service
Args:
bus (dbus.Bus): Bus
service (str): the service to connect to (e.g., org.freedesktop.DBus)
search_path (str, optional): The path to search in. Defaults to "/".
current_path (str, optional): Used in iterations. Defaults to "".
paths (list, optional): Current found paths. Defaults to None.
Returns:
list: Found paths
"""
if paths is None:
paths = []
if not search_path.startswith("/"):
search_path = "/" + search_path
if current_path == "":
current_path = search_path
if search_path != current_path and current_path not in paths:
paths.append(current_path)
obj = bus.get_object(service, current_path)
# adapted from https://unix.stackexchange.com/a/203678
iface = dbus.Interface(obj, "org.freedesktop.DBus.Introspectable")
xml_string = iface.Introspect()
for child in ElementTree.fromstring(xml_string):
if child.tag == "node":
if current_path == "/":
current_path = ""
new_path = "/".join((current_path, child.attrib["name"]))
list_paths(bus, service, search_path, new_path, paths)
return paths


if __name__ == "__main__":

session_bus = dbus.SessionBus()
print(
list_paths(
session_bus, "org.kde.konsole-311544", "/Sessions", "", ["/Sessions/1"]
)
)
print(list_paths(session_bus, "org.kde.plasmashell"))
26 changes: 7 additions & 19 deletions src/kde_material_you_colors/utils/konsole_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import dbus
from kde_material_you_colors.utils.color_utils import hex2rgb
from kde_material_you_colors.utils.string_utils import tup2str
from kde_material_you_colors.utils.dbus_utils import list_paths
from kde_material_you_colors import settings
from kde_material_you_colors.schemeconfigs import ThemeConfig

Expand Down Expand Up @@ -121,7 +122,7 @@ def export_scheme(
config.write(configfile, space_around_delimiters=False)


def apply_color_scheme(qdbus_executable: str):
def apply_color_scheme():
"""Applies the color scheme to the existing default profile or a new one"""
profile_name = set_default_profile(settings.KONSOLE_DEFAULT_THEMED_PROFILE)
profile_path = settings.KONSOLE_DIR + profile_name + ".profile"
Expand Down Expand Up @@ -157,10 +158,10 @@ def apply_color_scheme(qdbus_executable: str):
except Exception as e:
logging.exception(f"Error applying Konsole profile:\n{e}")

reload_profile(profile_name, qdbus_executable)
reload_profile(profile_name)


def reload_profile(profile: str, qdbus_executable: str):
def reload_profile(profile: str):
"""Reload the konsole profile for all running konsole sessions
Args:
Expand All @@ -175,26 +176,13 @@ def reload_profile(profile: str, qdbus_executable: str):

if konsole_dbus_services:
logging.debug(
f"Konsole services (windows) running ({len(konsole_dbus_services)}):"
f"Konsole services (windows) running: {len(konsole_dbus_services)}"
)
for service in konsole_dbus_services:
try:
# get open sessions (tabs and splits)
cmd = [qdbus_executable, service]
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
check=True,
)

sessions = [
line
for line in result.stdout.splitlines()
if line.startswith("/Sessions/")
]
logging.debug(f"{service} ({len(sessions)} sessions)")
sessions = list_paths(bus, service, "/Sessions")
logging.debug(f"window: {service} sessions: {len(sessions)}")

# reload colors by switching profiles
for session in sessions:
Expand Down
42 changes: 21 additions & 21 deletions src/kde_material_you_colors/utils/kwin_utils.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import logging
import subprocess
import time
import re
import dbus
import dbus.lowlevel
from kde_material_you_colors import settings


def reload(qdbus_executable: str):
logging.info(f"Reloading KWin")
subprocess.Popen(
qdbus_executable + " org.kde.KWin /KWin reconfigure",
shell=True,
stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
def reload():
logging.info("Reloading KWin")

bus = dbus.SessionBus()
kwin = dbus.Interface(
bus.get_object("org.kde.KWin", "/KWin"),
dbus_interface="org.kde.KWin",
)
kwin.reconfigure()


def klassy_update_decoration_color_cache():
Expand All @@ -39,7 +41,7 @@ def blend_changes():
)


def load_desktop_window_id_script(qdbus_executable: str):
def load_desktop_window_id_script():
# based on https://github.com/jinliu/kdotool/blob/master/src/main.rs 7eebebe
is_loaded = False
try:
Expand Down Expand Up @@ -69,27 +71,27 @@ def load_desktop_window_id_script(qdbus_executable: str):
logging.exception(f"An unexpected error occurred: {e}")
raise

# Calling this overloaded method raises TypeError:
# Fewer items found in D-Bus signature than in Python arguments
# So have use subprocess with qdbus instead :(
try:
# Construct the command with the necessary arguments
command = [
qdbus_executable,
"gdbus",
"call",
"--session",
"--dest",
"org.kde.KWin",
"--object-path",
"/Scripting",
"--method",
"org.kde.kwin.Scripting.loadScript",
settings.KWIN_DESKTOP_ID_JSCRIPT,
"kde_material_you_get_desktop_view_id",
]

# Execute the command and decode the output
result = subprocess.run(command, capture_output=True, text=True, check=True)
script_id = result.stdout.strip()
# keep only the id
script_id = re.sub(r"\D", "", result.stdout.strip())

# logging.debug(f"Script loaded id: {command}")

# Check if the script_id is an integer and convert it
if script_id.isdigit():
return script_id
else:
Expand All @@ -103,9 +105,7 @@ def load_desktop_window_id_script(qdbus_executable: str):
raise


def get_desktop_window_id(
screen: int = 0, qdbus_executable: str = "qdbus6"
) -> str | None:
def get_desktop_window_id(screen: int = 0) -> str | None:
# based on https://github.com/jinliu/kdotool/blob/master/src/main.rs 7eebebe
"""_summary_
Expand Down Expand Up @@ -142,9 +142,9 @@ def get_desktop_window_id(
with open(settings.KWIN_DESKTOP_ID_JSCRIPT, "w", encoding="utf-8") as js:
js.write(script_str)

# Load the script using qdbus
# Load the script
try:
script_id = load_desktop_window_id_script(qdbus_executable)
script_id = load_desktop_window_id_script()
except Exception as error:
logging.error(error)
raise
Expand Down
Loading

0 comments on commit 19597f6

Please sign in to comment.