Pull gnome-specific portions of UI out so UI package can be reused for breezy-box

This commit is contained in:
wheaney 2026-06-12 13:18:13 -07:00
parent 254fff37ff
commit ece35f9af0
18 changed files with 400 additions and 111 deletions

View File

@ -97,7 +97,7 @@ popd
UI_BUILD_ARTIFACT=$UI_DIR/out/breezyUI-$ARCH.tar.gz
if [ ! -e "$UI_BUILD_ARTIFACT" ] || [ "$1" == "--rebuild-ui" ] || [ "$1" == "--rebuild-all" ]; then
pushd $UI_DIR
bin/package $ARCH
RUNTIME_DIR=$GNOME_DIR/ui bin/package $ARCH
popd
fi
tar -xf $UI_BUILD_ARTIFACT -C $PACKAGE_DIR

View File

@ -0,0 +1,106 @@
"""GNOME Shell runtime environment for Breezy Desktop.
This is the reference RuntimeEnvironment implementation. It is packaged into the
UI's ``runtimes`` subpackage by the GNOME package script (see bin/package_gnome
-> ui/bin/package), so its imports are relative to the installed
``breezydesktop`` package.
"""
import logging
import os
import pydbus
from ..runtimeenvironment import RuntimeEnvironment
logger = logging.getLogger('breezy_ui')
BREEZY_DESKTOP_UUID = "breezydesktop@xronlinux.com"
EXTENSION_STATE_ENABLED = 1
class BreezyGNOMERuntimeEnvironment(RuntimeEnvironment):
"""Runs Breezy Desktop as a GNOME Shell extension.
Enablement is backed by the GNOME Shell extension state, verification runs
the breezy_gnome_verify binary, updates are checked against GitHub, and
virtual displays are created via the Mutter ScreenCast portal.
"""
APP_NAMESPACE = 'breezy_gnome'
def __init__(self):
super().__init__()
self.bus = pydbus.SessionBus()
self.gnome_shell_extensions = self.bus.get("org.gnome.Shell.Extensions")
self.gnome_shell_extensions.ExtensionStateChanged.connect(self._handle_extension_state_change)
self._breezy_enabled = self.is_enabled()
def _handle_extension_state_change(self, extension_uuid, state):
if extension_uuid == BREEZY_DESKTOP_UUID:
enabled = state.get('state') == EXTENSION_STATE_ENABLED
# update internal state first so do_set_property doesn't re-trigger
# an extension enable/disable; this just emits the notify
self._breezy_enabled = enabled
self.set_property('breezy-enabled', enabled)
# --- effect enablement ------------------------------------------------
def is_installed(self):
extensions_result = self.gnome_shell_extensions.ListExtensions()
for extension in extensions_result:
if extension == BREEZY_DESKTOP_UUID:
return True
return False
def is_enabled(self):
return self.gnome_shell_extensions.GetExtensionInfo(BREEZY_DESKTOP_UUID).get('state') == EXTENSION_STATE_ENABLED
def enable(self):
if not self.gnome_shell_extensions.UserExtensionsEnabled:
self.gnome_shell_extensions.UserExtensionsEnabled = True
self.gnome_shell_extensions.EnableExtension(BREEZY_DESKTOP_UUID)
self._breezy_enabled = True
def disable(self):
self.gnome_shell_extensions.DisableExtension(BREEZY_DESKTOP_UUID)
self._breezy_enabled = False
# --- verification / updates -------------------------------------------
def verify(self):
from .verify import verify_installation
return verify_installation()
def check_for_update(self, current_version, callback):
from .updatechecker import check_for_update
return check_for_update(current_version, callback)
# --- optional views ---------------------------------------------------
@property
def shows_no_device_view(self):
return True
# --- virtual displays -------------------------------------------------
def is_virtual_display_supported(self):
# wayland + the Mutter ScreenCast portal are required to create displays
from .virtualdisplay import is_screencast_available
return is_screencast_available() and "WAYLAND_DISPLAY" in os.environ
def _create_virtual_display_manager(self):
from .virtualdisplaymanager import VirtualDisplayManager
return VirtualDisplayManager.get_instance()
# --- GObject property plumbing ----------------------------------------
def do_set_property(self, prop, value):
if prop.name == 'breezy-enabled' and value != self._breezy_enabled:
self.enable() if value else self.disable()
def do_get_property(self, prop):
if prop.name == 'breezy-enabled':
return self._breezy_enabled

View File

@ -2,7 +2,7 @@ import logging
import os
import subprocess
from .files import get_bin_home
from ..files import get_bin_home
logger = logging.getLogger('breezy_ui')

View File

@ -12,7 +12,7 @@ logger = logging.getLogger('breezy_ui')
gi.require_version('GLib', '2.0')
from gi.repository import GLib, GObject
from .files import get_bin_home
from ..files import get_bin_home
class VirtualDisplayManager(GObject.GObject):
__gproperties__ = {

View File

@ -6,6 +6,18 @@ set -e
ARCH=${ARCH:-$(uname -m)}
echo "Building Breezy UI for $ARCH"
# Directory containing the RuntimeEnvironment implementation(s) to bundle. Every
# *.py in here is copied into the UI's runtimes/ package; the first
# RuntimeEnvironment subclass found at startup becomes the active environment.
# Defaults to the reference GNOME implementation so a standalone UI build (e.g.
# local dev) still has a runtime.
RUNTIME_DIR=${RUNTIME_DIR:-$(realpath "$(dirname "$0")/../../gnome/ui")}
echo "Bundling runtime environment from $RUNTIME_DIR"
if [ ! -d "$RUNTIME_DIR" ]; then
echo "Runtime directory $RUNTIME_DIR does not exist"
exit 1
fi
BUILD_PATH=build
UI_BUILD_PATH=$BUILD_PATH/ui
PACKAGE_DIR=$BUILD_PATH/breezy_ui
@ -38,6 +50,12 @@ mkdir -p $PACKAGE_SCHEMAS_DIR
cp src/*.py $PACKAGE_BREEZY_SRC_DIR
cp -r lib $PACKAGE_BREEZY_SRC_DIR
# bundle the runtimes subpackage and the selected runtime implementation(s)
PACKAGE_RUNTIMES_DIR=$PACKAGE_BREEZY_SRC_DIR/runtimes
mkdir -p $PACKAGE_RUNTIMES_DIR
cp src/runtimes/__init__.py $PACKAGE_RUNTIMES_DIR
cp $RUNTIME_DIR/*.py $PACKAGE_RUNTIMES_DIR
cp -L modules/PyXRLinuxDriverIPC/xrdriveripc.py $PACKAGE_BREEZY_SRC_DIR
cp $UI_BUILD_PATH/src/breezydesktop.gresource $PACKAGE_BREEZY_DIR
cp -r po/mo/* $PACKAGE_LOCALE_DIR

View File

@ -2,14 +2,12 @@ from gi.repository import Gio, GLib, Gtk, GObject
from .configmanager import ConfigManager
from .customresolutiondialog import CustomResolutionDialog
from .displaydistancedialog import DisplayDistanceDialog
from .extensionsmanager import ExtensionsManager
from .files import get_state_dir
from .license import BREEZY_GNOME_FEATURES
from .runtimeenvironment import RuntimeEnvironment
from .settingsmanager import SettingsManager
from .shortcutdialog import bind_shortcut_settings
from .statemanager import StateManager
from .virtualdisplaymanager import VirtualDisplayManager
from .virtualdisplay import is_screencast_available
from .virtualdisplayrow import VirtualDisplayRow
from .xrdriveripc import XRDriverIPC
@ -115,8 +113,8 @@ class ConnectedDevice(Gtk.Box):
self.settings = SettingsManager.get_instance().settings
self.desktop_settings = SettingsManager.get_instance().desktop_settings
self.ipc = XRDriverIPC.get_instance()
self.virtual_display_manager = VirtualDisplayManager.get_instance()
self.extensions_manager = ExtensionsManager.get_instance()
self.runtime = RuntimeEnvironment.get_instance()
self.virtual_display_manager = self.runtime.virtual_display_manager
self.settings.bind('disable-physical-displays', self.disable_physical_displays_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
self.settings.connect('changed::display-distance', self._handle_display_distance)
@ -207,7 +205,7 @@ class ConnectedDevice(Gtk.Box):
self._handle_device_supports_sbs(self.state_manager, None)
self._handle_enabled_config(None, None)
self._refresh_use_optimal_monitor_config(self.use_optimal_monitor_config_switch, None)
self.extensions_manager.connect('notify::breezy-enabled', self._handle_enabled_config)
self.runtime.connect('notify::breezy-enabled', self._handle_enabled_config)
self._settings_displays_app_info = None
@ -229,9 +227,6 @@ class ConnectedDevice(Gtk.Box):
for id in self._custom_resolution_options:
self.add_virtual_display_menu.insert(self._default_resolution_options_count, id, id)
# wayland is required to create virtual displays
self.is_wayland = "WAYLAND_DISPLAY" in os.environ
def _bind_scale_to_config(self, scale, config_key):
self.config_manager.bind_property(config_key, scale, 'value', Gio.SettingsBindFlags.DEFAULT)
scale.set_value(self.config_manager.get_property(config_key))
@ -285,7 +280,7 @@ class ConnectedDevice(Gtk.Box):
# self.widescreen_mode_row.set_subtitle(subtitle)
def _handle_enabled_config(self, object, val):
enabled = self.config_manager.get_property('breezy-desktop-enabled') and self.extensions_manager.get_property('breezy-enabled')
enabled = self.config_manager.get_property('breezy-desktop-enabled') and self.runtime.get_property('breezy-enabled')
if enabled != self.effect_enable_switch.get_active():
self.effect_enable_switch.set_active(enabled)
@ -297,14 +292,14 @@ class ConnectedDevice(Gtk.Box):
# never turn off the extension, disabling the effect is done via configs only
if requesting_enabled:
self.extensions_manager.set_property('breezy-enabled', True)
self.runtime.set_property('breezy-enabled', True)
self.config_manager.set_property('breezy-desktop-enabled', requesting_enabled)
for widget in self.all_enabled_state_inputs:
widget.set_sensitive(requesting_enabled)
if not is_screencast_available() or not self.is_wayland:
if not self.runtime.is_virtual_display_supported():
self.virtual_displays_row.set_subtitle(
_("Unable to add virtual displays on this machine. Wayland, xdg-desktop-portal, and the pipewire GStreamer plugin are required."))
self.add_virtual_display_button.set_sensitive(False)

View File

@ -1,72 +0,0 @@
import pydbus
from gi.repository import GObject
BREEZY_DESKTOP_UUID = "breezydesktop@xronlinux.com"
EXTENSION_STATE_ENABLED = 1
class ExtensionsManager(GObject.GObject):
__gproperties__ = {
'breezy-enabled': (bool, 'Breezy Enabled', 'Whether the Breezy Desktop GNOME extension is enabled', False, GObject.ParamFlags.READWRITE)
}
_instance = None
@staticmethod
def get_instance():
if ExtensionsManager._instance is None:
ExtensionsManager._instance = ExtensionsManager()
return ExtensionsManager._instance
def __init__(self):
GObject.GObject.__init__(self)
self.bus = pydbus.SessionBus()
self.gnome_shell_extensions = self.bus.get("org.gnome.Shell.Extensions")
self.gnome_shell_extensions.ExtensionStateChanged.connect(self._handle_extension_state_change)
self.remote_extension_state = self.is_enabled()
def _handle_extension_state_change(self, extension_uuid, state):
if extension_uuid == BREEZY_DESKTOP_UUID:
self.remote_extension_state = state.get('state') == EXTENSION_STATE_ENABLED
self.set_property('breezy-enabled', self.remote_extension_state)
def is_installed(self):
return self._is_installed(BREEZY_DESKTOP_UUID)
def enable(self):
self._enable_extension(BREEZY_DESKTOP_UUID)
def disable(self):
self._disable_extension(BREEZY_DESKTOP_UUID)
def is_enabled(self):
return self._is_enabled(BREEZY_DESKTOP_UUID)
def _is_installed(self, extension_uuid):
extensions_result = self.gnome_shell_extensions.ListExtensions()
for extension in extensions_result:
if extension == extension_uuid:
return True
return False
def _enable_extension(self, extension_uuid):
if not self.gnome_shell_extensions.UserExtensionsEnabled:
self.gnome_shell_extensions.UserExtensionsEnabled = True
self.gnome_shell_extensions.EnableExtension(extension_uuid)
def _disable_extension(self, extension_uuid):
self.gnome_shell_extensions.DisableExtension(extension_uuid)
def _is_enabled(self, extension_uuid):
return self.gnome_shell_extensions.GetExtensionInfo(extension_uuid).get('state') == EXTENSION_STATE_ENABLED
def do_set_property(self, prop, value):
if prop.name == 'breezy-enabled' and value != self.remote_extension_state:
self.enable() if value == True else self.disable()
def do_get_property(self, prop):
if prop.name == 'breezy-enabled':
return self.remote_extension_state

View File

@ -10,8 +10,11 @@ def get_config_dir():
return os.path.expanduser(config_home)
def get_state_dir():
# imported lazily to avoid an import cycle (runtime discovery imports
# modules that import this one)
from .runtime import runtime_namespace
state_home = os.environ.get('XDG_STATE_HOME', '~/.local/state')
return os.path.join(os.path.expanduser(state_home), 'breezy_gnome')
return os.path.join(os.path.expanduser(state_home), runtime_namespace())
def get_data_home():
data_home = os.environ.get('XDG_DATA_HOME', '~/.local/share')

View File

@ -42,7 +42,6 @@ breezydesktop_sources = [
'connecteddevice.py',
'customresolutiondialog.py',
'customresolutiondialogcontent.py',
'extensionsmanager.py',
'displaydistancedialog.py',
'displaydistancedialogcontent.py',
'failedverification.py',
@ -57,16 +56,18 @@ breezydesktop_sources = [
'nodriver.py',
'noextension.py',
'nolicense.py',
'runtime.py',
'runtimeenvironment.py',
'settingsmanager.py',
'shortcutdialog.py',
'statemanager.py',
'time.py',
'updatechecker.py',
'virtualdisplay.py',
'virtualdisplaymanager.py',
'verify.py',
'window.py'
]
install_data(breezydesktop_sources, install_dir: moduledir)
install_subdir('../lib', install_dir: moduledir)
install_subdir('../lib', install_dir: moduledir)
# the runtimes subpackage marker; a concrete RuntimeEnvironment implementation
# is copied in per-build by the package script (see ui/bin/package).
install_data('runtimes/__init__.py', install_dir: moduledir / 'runtimes')

View File

@ -1,6 +1,6 @@
from gi.repository import Gio, Gtk
from .configmanager import ConfigManager
from .extensionsmanager import ExtensionsManager
from .runtimeenvironment import RuntimeEnvironment
from .settingsmanager import SettingsManager
from .statemanager import StateManager
from .xrdriveripc import XRDriverIPC
@ -18,7 +18,7 @@ class NoDevice(Gtk.Box):
self.init_template()
self.ipc = XRDriverIPC.get_instance()
self.extensions_manager = ExtensionsManager.get_instance()
self.runtime = RuntimeEnvironment.get_instance()
self.settings = SettingsManager.get_instance().settings
self.config_manager = ConfigManager.get_instance()
self.config_manager.connect('notify::breezy-desktop-enabled', self._handle_enabled_config)
@ -30,16 +30,16 @@ class NoDevice(Gtk.Box):
self._handle_enabled_config(self.config_manager, None)
def _handle_enabled_config(self, config_manager, val):
enabled = config_manager.get_property('breezy-desktop-enabled') and self.extensions_manager.get_property('breezy-enabled')
enabled = config_manager.get_property('breezy-desktop-enabled') and self.runtime.get_property('breezy-enabled')
if enabled != self.effect_enable_switch.get_active():
self.effect_enable_switch.set_active(enabled)
def _handle_switch_enabled_state(self, switch, param):
requesting_enabled = switch.get_active()
# never turn off the extension, disabling the effect is done via configs only
if requesting_enabled:
self.extensions_manager.set_property('breezy-enabled', True)
self.runtime.set_property('breezy-enabled', True)
self.config_manager.set_property('breezy-desktop-enabled', requesting_enabled)

63
ui/src/runtime.py Normal file
View File

@ -0,0 +1,63 @@
"""Runtime environment discovery.
Exactly one concrete :class:`~breezydesktop.runtimeenvironment.RuntimeEnvironment`
implementation is bundled into the ``runtimes`` subpackage at package time. This
module finds it (the first one it sees) and exposes both the class and a cheap
way to read its namespace without constructing the (potentially side-effectful)
instance.
"""
import importlib
import inspect
import logging
import pkgutil
from .runtimeenvironment import RuntimeEnvironment, DEFAULT_APP_NAMESPACE
logger = logging.getLogger('breezy_ui')
_runtime_class = None
def get_runtime_class():
"""Return the active RuntimeEnvironment subclass.
Scans the bundled ``runtimes`` subpackage and returns the first concrete
RuntimeEnvironment subclass found. The result is cached. Raises
RuntimeError if no implementation is bundled.
"""
global _runtime_class
if _runtime_class is not None:
return _runtime_class
from . import runtimes
for module_info in pkgutil.iter_modules(runtimes.__path__, runtimes.__name__ + '.'):
try:
module = importlib.import_module(module_info.name)
except Exception as e:
logger.error("Failed to import runtime module %s: %s", module_info.name, e)
continue
for _, obj in inspect.getmembers(module, inspect.isclass):
if issubclass(obj, RuntimeEnvironment) and obj is not RuntimeEnvironment \
and obj.__module__ == module_info.name:
logger.info("Using runtime environment %s", obj.__name__)
_runtime_class = obj
return _runtime_class
raise RuntimeError(
"No RuntimeEnvironment implementation was found in the 'runtimes' package. "
"A runtime implementation must be bundled at package time.")
def runtime_namespace():
"""Return the active runtime's application namespace.
Falls back to the default namespace if no runtime is bundled, so early
bootstrap paths (e.g. log directory setup) never fail.
"""
try:
return get_runtime_class().app_namespace()
except RuntimeError:
return DEFAULT_APP_NAMESPACE

View File

@ -0,0 +1,169 @@
import gettext
from gi.repository import GObject
_ = gettext.gettext
# Default namespace used for XDG directories, application identity, etc. A
# concrete RuntimeEnvironment should override APP_NAMESPACE.
DEFAULT_APP_NAMESPACE = 'breezy_gnome'
class NullVirtualDisplayManager(GObject.GObject):
"""A no-op virtual display manager.
Provides the same interface (the 'displays' property + change
notifications, plus create/destroy methods) that the UI binds to, but
never creates anything. Runtime environments that don't support virtual
displays can use this so the UI degrades gracefully.
"""
__gproperties__ = {
'displays': (object, 'Displays', 'A list of the displays', GObject.ParamFlags.READWRITE)
}
def __init__(self):
GObject.GObject.__init__(self)
self._displays = []
def create_virtual_display(self, width, height, framerate):
return None
def destroy_virtual_display(self, pid):
return False
def do_set_property(self, prop, value):
if prop.name == 'displays':
self._displays = value
def do_get_property(self, prop):
if prop.name == 'displays':
return self._displays
class RuntimeEnvironment(GObject.GObject):
"""Abstraction over the host environment the UI is running in.
A RuntimeEnvironment encapsulates everything that differs between the
environments Breezy can run in (e.g. GNOME Shell vs. a headless Breezy Box):
how the effect is enabled, how the installation is verified, whether/how
updates are checked, how virtual displays are managed, and which optional
views and fields the UI should present.
The first concrete subclass discovered in the bundled ``runtimes`` package
(see :mod:`breezydesktop.runtime`) is instantiated as the active
environment, so a build can swap behavior simply by packaging a different
implementation.
Subclasses inherit the ``breezy-enabled`` GObject property; override
:meth:`enable`/:meth:`disable`/:meth:`is_enabled` (and, if needed,
``do_set_property``/``do_get_property``) to back it with real state.
"""
# The application/namespace identifier, e.g. 'breezy_gnome' or 'breezy_box'.
# Used for namespacing XDG directories and similar. Subclasses must set
# this.
APP_NAMESPACE = None
__gproperties__ = {
'breezy-enabled': (bool, 'Breezy Enabled', 'Whether the Breezy Desktop effect is enabled', False, GObject.ParamFlags.READWRITE)
}
_instance = None
@classmethod
def get_instance(cls):
if RuntimeEnvironment._instance is None:
from .runtime import get_runtime_class
RuntimeEnvironment._instance = get_runtime_class()()
return RuntimeEnvironment._instance
def __init__(self):
GObject.GObject.__init__(self)
self._breezy_enabled = False
self._virtual_display_manager = None
# --- identity ---------------------------------------------------------
@classmethod
def app_namespace(cls):
return cls.APP_NAMESPACE or DEFAULT_APP_NAMESPACE
# --- effect enablement (backs the 'breezy-enabled' property) ----------
def is_installed(self):
"""Whether the supporting components for this environment are installed.
Environments with no separate component to install (e.g. a headless
box where the runtime is always present) should return True.
"""
return True
def is_enabled(self):
return self._breezy_enabled
def enable(self):
self._breezy_enabled = True
def disable(self):
self._breezy_enabled = False
# --- verification -----------------------------------------------------
def verify(self):
"""Verify the installation. Return True when verification passes (or
when the environment has no verification step)."""
return True
# --- update checking --------------------------------------------------
def check_for_update(self, current_version, callback):
"""Asynchronously check for a newer version.
Implementations that support updates should invoke
``callback(latest_version_str)`` when a newer version is available.
The default is a no-op (no update prompt).
"""
return None
# --- optional views / fields ------------------------------------------
@property
def shows_no_device_view(self):
"""Whether a dedicated "no device connected" view should be shown.
When False, the connected-device view is always shown and
:meth:`no_device_label` supplies the label used when no device is
actually connected.
"""
return False
def no_device_label(self):
"""Label shown in place of a device name when no device is connected
(only relevant when :attr:`shows_no_device_view` is False)."""
return _("No supported glasses connected")
# --- virtual displays -------------------------------------------------
def is_virtual_display_supported(self):
return False
def _create_virtual_display_manager(self):
"""Build the virtual display manager for this environment. Override to
provide a real implementation."""
return NullVirtualDisplayManager()
@property
def virtual_display_manager(self):
if self._virtual_display_manager is None:
self._virtual_display_manager = self._create_virtual_display_manager()
return self._virtual_display_manager
# --- GObject property plumbing ----------------------------------------
def do_set_property(self, prop, value):
if prop.name == 'breezy-enabled' and value != self.is_enabled():
self.enable() if value else self.disable()
def do_get_property(self, prop):
if prop.name == 'breezy-enabled':
return self.is_enabled()

View File

@ -0,0 +1,7 @@
"""Bundled runtime environment implementations.
Exactly one concrete RuntimeEnvironment implementation module is copied into
this package at package time (see ui/bin/package). The implementation is
selected per-build from a runtime source directory (e.g. gnome/ui), so behavior
can be swapped without touching the core UI.
"""

View File

@ -85,8 +85,8 @@ def create_display(width, height, framerate):
sys.exit(1)
if __name__ == "__main__":
from breezydesktop import virtualdisplay
from breezydesktop.virtualdisplay import VirtualDisplay
from breezydesktop.runtimes import virtualdisplay
from breezydesktop.runtimes.virtualdisplay import VirtualDisplay
global virtual_display_instance
global loop

View File

@ -1,5 +1,5 @@
from gi.repository import Adw, Gtk
from .virtualdisplaymanager import VirtualDisplayManager
from .runtimeenvironment import RuntimeEnvironment
import gettext
@ -28,4 +28,4 @@ class VirtualDisplayRow(Adw.ActionRow):
self.remove_virtual_display_button.connect('clicked', self._remove_virtual_display)
def _remove_virtual_display(self, widget):
VirtualDisplayManager.get_instance().destroy_virtual_display(self.pid)
RuntimeEnvironment.get_instance().virtual_display_manager.destroy_virtual_display(self.pid)

View File

@ -1,7 +1,7 @@
from gi.repository import Gtk, GLib
from .extensionsmanager import ExtensionsManager
from .license import BREEZY_GNOME_FEATURES
from .licensedialog import LicenseDialog
from .runtimeenvironment import RuntimeEnvironment
from .statemanager import StateManager
from .settingsmanager import SettingsManager
from .connecteddevice import ConnectedDevice
@ -10,8 +10,6 @@ from .nodevice import NoDevice
from .nodriver import NoDriver
from .noextension import NoExtension
from .nolicense import NoLicense
from .updatechecker import check_for_update
from .verify import verify_installation
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/window.ui')
class BreezydesktopWindow(Gtk.ApplicationWindow):
@ -29,6 +27,7 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
def __init__(self, version, skip_verification, **kwargs):
super().__init__(**kwargs)
self.runtime = RuntimeEnvironment.get_instance()
self.connected_device = ConnectedDevice()
self.failed_verification = FailedVerification()
self.no_device = NoDevice()
@ -57,7 +56,7 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
self.connect("destroy", self._on_window_destroy)
check_for_update(version, self._on_update_check_result)
self.runtime.check_for_update(version, self._on_update_check_result)
def _handle_settings_update(self, settings_manager, key):
self._handle_state_update(self.state_manager, None)
@ -82,19 +81,19 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
if self.settings.get_boolean('debug-no-device'):
self.main_content.append(self.connected_device)
self.connected_device.set_device_name('Fake device')
elif not self._skip_verification and not verify_installation():
elif not self._skip_verification and not self.runtime.verify():
self.main_content.append(self.failed_verification)
elif not ExtensionsManager.get_instance().is_installed():
elif not self.runtime.is_installed():
self.main_content.append(self.no_extension)
elif not self.state_manager.driver_running:
self.main_content.append(self.no_driver)
elif not self.state_manager.license_present:
self.main_content.append(self.no_license)
elif not state_manager.connected_device_name:
elif not state_manager.connected_device_name and self.runtime.shows_no_device_view:
self.main_content.append(self.no_device)
else:
self.main_content.append(self.connected_device)
self.connected_device.set_device_name(state_manager.connected_device_name)
self.connected_device.set_device_name(state_manager.connected_device_name or self.runtime.no_device_label())
self.set_resizable(True)
self.set_default_size(1, 1)