diff --git a/flatpak/entrypoint b/flatpak/entrypoint index 38fd86f451..0c8e163fdc 100644 --- a/flatpak/entrypoint +++ b/flatpak/entrypoint @@ -6,4 +6,11 @@ grep -q org.freedesktop.Platform.GL.nvidia /.flatpak-info && export WEBKIT_DISAB # Work-around https://github.com/bambulab/BambuStudio/issues/3440 export LC_ALL=C.UTF-8 -exec /app/bin/orca-slicer "$@" +if XDG_CONFIG_HOME=$HOME/.config /app/bin/uses-dark-theme.py; then + export GTK_THEME='Adwaita:dark' + export ORCA_SLICER_DARK_THEME='true' + echo "Message: $(date +%T): INFO: using dark theme variant" +fi + +exec /app/bin/orca-slicer "$@" & +$(/app/bin/set-dark-theme-variant.py) & diff --git a/flatpak/io.github.softfever.OrcaSlicer.yml b/flatpak/io.github.softfever.OrcaSlicer.yml index b3ca946e38..ae29d671de 100755 --- a/flatpak/io.github.softfever.OrcaSlicer.yml +++ b/flatpak/io.github.softfever.OrcaSlicer.yml @@ -19,8 +19,34 @@ finish-args: - --talk-name=io.github.softfever.OrcaSlicer.InstanceCheck.* - --system-talk-name=org.freedesktop.UDisks2 - --env=SPNAV_SOCKET=/run/spnav.sock + # set dark theme + - --env=ORCA_SLICER_DARK_THEME=false modules: + # xprop, xlib is needed to manipulate the X11 window and set _GTK_THEME_VARIANT dark on X11 + # and paint the window dark when ORCA_SLICER_DARK_THEME is true + # see: entrypoint & set-dark-theme-variant.py (originated from Pursa Slicer flatpak which originated from spotify client flatpak) + - name: xprop + sources: + - type: archive + url: https://xorg.freedesktop.org/archive/individual/app/xprop-1.2.5.tar.gz + sha256: b7bf6b6be6cf23e7966a153fc84d5901c14f01ee952fbd9d930aa48e2385d670 + - name: python-setuptools_scm + buildsystem: simple + build-commands: + - pip3 install --no-deps --no-build-isolation --verbose --prefix=${FLATPAK_DEST} . + sources: + - type: archive + url: https://files.pythonhosted.org/packages/57/38/930b1241372a9f266a7df2b184fb9d4f497c2cef2e016b014f82f541fe7c/setuptools_scm-6.0.1.tar.gz + sha256: d1925a69cb07e9b29416a275b9fadb009a23c148ace905b2fb220649a6c18e92 + - name: python-xlib + buildsystem: simple + build-commands: + - pip3 install --no-deps --no-build-isolation --verbose --prefix=${FLATPAK_DEST} . + sources: + - type: archive + url: https://files.pythonhosted.org/packages/86/f5/8c0653e5bb54e0cbdfe27bf32d41f27bc4e12faa8742778c17f2a71be2c0/python-xlib-0.33.tar.gz + sha256: 55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 # JPEG codec for the liveview - name: gst-plugins-good @@ -299,6 +325,8 @@ modules: desktop-file-edit --set-key=Exec --set-value="entrypoint %U" /app/share/applications/${FLATPAK_ID}.desktop install -Dm755 entrypoint /app/bin install -Dm755 umount /app/bin + install set-dark-theme-variant.py /app/bin + install uses-dark-theme.py /app/bin sources: # - @@ -316,6 +344,14 @@ modules: - type: file path: io.github.softfever.OrcaSlicer.metainfo.xml + # script to set dark theme variant + - type: file + path: set-dark-theme-variant.py + + # script to detect if host uses dark theme + - type: file + path: uses-dark-theme.py + # start-up script - type: file path: entrypoint diff --git a/flatpak/set-dark-theme-variant.py b/flatpak/set-dark-theme-variant.py new file mode 100644 index 0000000000..2f05be0fe5 --- /dev/null +++ b/flatpak/set-dark-theme-variant.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +import Xlib +import Xlib.display +import time +import subprocess +import os +import sys + + +disp = Xlib.display.Display() +root = disp.screen().root + +NET_CLIENT_LIST = disp.intern_atom('_NET_CLIENT_LIST') + + +def set_theme_variant_by_window_id(id, variant): + # Use subprocess to call + # xprop and set the variant from id. + try: + s = subprocess.call(['xprop', '-f', '_GTK_THEME_VARIANT', '8u', '-set', '_GTK_THEME_VARIANT', variant, '-id', str(id)], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + if s == 0: + return True + return False + except Exception as ex: + return False + + +def set_theme_variant_from_win_id_collection(win_id_collection, variant): + # Loop though all of the collected + # window ids and set theme variant + for win_id in win_id_collection: + set_theme_variant_by_window_id(win_id, variant) + + +def collection_win_id_from_wm_class_name(win_class_name): + + collect = [] + + # Loop though all of the windows + # and collect id's those that match + # win_class: prusa-slicer + for win_id in root.get_full_property(NET_CLIENT_LIST, Xlib.X.AnyPropertyType).value: + try: + win = disp.create_resource_object('window', win_id) + if not win.get_wm_transient_for(): + win_class = win.get_wm_class() + if win_id and win_class_name in win_class: + collect.append( + win_id) if win_id not in collect else collect + except Xlib.error.BadWindow: + pass + + return collect + + +if __name__ == '__main__': + + if os.environ.get('ORCA_SLICER_DARK_THEME', 'false') != 'true': + sys.exit(0) + + # Listen for X Property Change events. + root.change_attributes(event_mask=Xlib.X.PropertyChangeMask) + # the class name of the slicer window + win_class_name = 'orcaslicer' + # the variant to set + variant = 'dark' + + start = time.time() + + while True: + # collect all of the window ids + collect = collection_win_id_from_wm_class_name(win_class_name) + # give Orca Slicer window 2 secs to + # collect the wanted window ids + # set the theme variant and exit + if time.time() - start <= 2: + # disp.next_event() blocks if no events are + # queued. In combination with while True + # it creates a very simple event loop. + disp.next_event() + set_theme_variant_from_win_id_collection(collect, variant) + else: + break diff --git a/flatpak/uses-dark-theme.py b/flatpak/uses-dark-theme.py new file mode 100644 index 0000000000..4d7ebbc87a --- /dev/null +++ b/flatpak/uses-dark-theme.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +import os +import sys +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk as gtk + + +if __name__ == '__main__': + forced = os.environ.get('ORCA_SLICER_DARK_THEME', 'false') == 'true' + settings = gtk.Settings.get_default() + prefer_dark = settings.get_property('gtk-application-prefer-dark-theme') + + if not forced and not prefer_dark: + sys.exit(1) + else: + sys.exit(0)