Add messaging if no running driver is detected

This commit is contained in:
wheaney 2024-07-25 13:04:18 -07:00
parent 56a7d41ec6
commit d1c5e9fc4d
8 changed files with 100 additions and 40 deletions

View File

@ -95,24 +95,30 @@ export default class BreezyDesktopExtension extends Extension {
var target_monitor = this._target_monitor;
var is_effect_running = this._is_effect_running;
this._running_poller_id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, (() => {
if (is_effect_running) {
this._running_poller_id = undefined;
return GLib.SOURCE_REMOVE;
}
const is_driver_running = this._check_driver_running();
if (is_driver_running && target_monitor) {
// Don't enable the effect yet if monitor updates are needed.
// _setup will be triggered again since a !ready result means it will trigger monitor changes,
// so we can remove this timeout_add no matter what.
if (this._target_monitor_ready(target_monitor)) {
Globals.logger.log('Driver is running, supported monitor connected. Enabling XR effect.');
this._effect_enable();
try {
if (is_effect_running) {
this._running_poller_id = undefined;
return GLib.SOURCE_REMOVE;
}
const is_driver_running = this._check_driver_running();
if (is_driver_running && target_monitor) {
// Don't enable the effect yet if monitor updates are needed.
// _setup will be triggered again since a !ready result means it will trigger monitor changes,
// so we can remove this timeout_add no matter what.
if (this._target_monitor_ready(target_monitor)) {
Globals.logger.log('Driver is running, supported monitor connected. Enabling XR effect.');
this._effect_enable();
}
this._running_poller_id = undefined;
return GLib.SOURCE_REMOVE;
} else {
return GLib.SOURCE_CONTINUE;
}
} catch (e) {
Globals.logger.log(`ERROR: BreezyDesktopExtension _poll_for_ready ${e.message}\n${e.stack}`);
this._running_poller_id = undefined;
return GLib.SOURCE_REMOVE;
} else {
return GLib.SOURCE_CONTINUE;
}
}).bind(this));
}
@ -333,29 +339,37 @@ export default class BreezyDesktopExtension extends Extension {
}
_write_control(key, value) {
const file = Gio.file_new_for_path('/dev/shm/xr_driver_control');
const stream = file.replace(null, false, Gio.FileCreateFlags.NONE, null);
stream.write(`${key}=${value}`, null);
stream.close(null);
try {
const file = Gio.file_new_for_path('/dev/shm/xr_driver_control');
const stream = file.replace(null, false, Gio.FileCreateFlags.NONE, null);
stream.write(`${key}=${value}`, null);
stream.close(null);
} catch (e) {
Globals.logger.log(`ERROR: BreezyDesktopExtension _write_control ${e.message}\n${e.stack}`);
}
}
_read_state(keys) {
const state = {};
const file = Gio.file_new_for_path('/dev/shm/xr_driver_state');
if (file.query_exists(null)) {
const data = file.load_contents(null);
if (data[0]) {
const bytes = new Uint8Array(data[1]);
const decoder = new TextDecoder();
const contents = decoder.decode(bytes);
try {
const file = Gio.file_new_for_path('/dev/shm/xr_driver_state');
if (file.query_exists(null)) {
const data = file.load_contents(null);
if (data[0]) {
const bytes = new Uint8Array(data[1]);
const decoder = new TextDecoder();
const contents = decoder.decode(bytes);
const lines = contents.split('\n');
for (const line of lines) {
const [k, v] = line.split('=');
if (keys.includes(k)) state[k] = v;
const lines = contents.split('\n');
for (const line of lines) {
const [k, v] = line.split('=');
if (keys.includes(k)) state[k] = v;
}
}
}
} catch (e) {
Globals.logger.log(`ERROR: BreezyDesktopExtension _read_state ${e.message}\n${e.stack}`);
}
return state;
}
@ -377,13 +391,14 @@ export default class BreezyDesktopExtension extends Extension {
this._write_control('sbs_mode', value ? 'enable' : 'disable');
if (!this._sbs_mode_update_timeout) {
var attempts = 0;
this._sbs_mode_update_timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 10000, (() => {
this._sbs_mode_update_timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 3000, (() => {
if (attempts++ < 3) {
this._write_control('sbs_mode', value ? 'enable' : 'disable');
return GLib.SOURCE_CONTINUE;
}
// the state never updated to reflect our request, revert the setting
Globals.logger.log('Failed to update sbs_mode state, reverting setting');
this.settings.set_boolean('widescreen-mode', !value);
this._sbs_mode_update_timeout = undefined;
return GLib.SOURCE_REMOVE;
@ -403,6 +418,7 @@ export default class BreezyDesktopExtension extends Extension {
_update_widescreen_mode_from_state(effect, _pspec) {
// kill our state checker if it's running
if (this._sbs_mode_update_timeout) {
Globals.logger.log_debug('BreezyDesktopExtension _update_widescreen_mode_from_state - clearing timeout');
GLib.source_remove(this._sbs_mode_update_timeout);
this._sbs_mode_update_timeout = undefined;
}
@ -448,8 +464,9 @@ export default class BreezyDesktopExtension extends Extension {
this._is_effect_running = false;
if (this._running_poller_id) {
GLib.source_remove(this._running_poller_id);
const poller_id = this._running_poller_id;
this._running_poller_id = undefined;
GLib.source_remove(poller_id);
}
Main.wm.removeKeybinding('recenter-display-shortcut');

@ -1 +1 @@
Subproject commit a96fdeb1557d8cd24e73cb8e9e2559adfa46e3aa
Subproject commit 3f23409b6be154c9c9a7035c6213558a7ef6c84e

View File

@ -5,6 +5,7 @@
<file preprocess="xml-stripblanks">gtk/failed-verification.ui</file>
<file preprocess="xml-stripblanks">gtk/license-dialog.ui</file>
<file preprocess="xml-stripblanks">gtk/no-device.ui</file>
<file preprocess="xml-stripblanks">gtk/no-driver.ui</file>
<file preprocess="xml-stripblanks">gtk/no-extension.ui</file>
<file preprocess="xml-stripblanks">gtk/no-license.ui</file>
<file preprocess="xml-stripblanks">gtk/shortcut-dialog.ui</file>

24
ui/src/gtk/no-driver.ui Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<template class="NoDriver" parent="GtkBox">
<property name="orientation">1</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="spacing">20</property>
<child>
<object class="AdwStatusPage">
<property name="title" translatable="true">No driver running</property>
<property name="description" translatable="true">
If you installed via AUR, make sure you ran the recommended post-install command:
systemctl --user enable --now xr-driver.service
Otherwise, please file an issue on GitHub, or create a new thread in the #troubleshooting channel on Discord.
</property>
<property name="width-request">650</property>
</object>
</child>
</template>
</interface>

View File

@ -38,6 +38,7 @@ breezydesktop_sources = [
'licensetierrow.py',
'main.py',
'nodevice.py',
'nodriver.py',
'noextension.py',
'nolicense.py',
'settingsmanager.py',

5
ui/src/nodriver.py Normal file
View File

@ -0,0 +1,5 @@
from gi.repository import Gtk
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/no-driver.ui')
class NoDriver(Gtk.Box):
__gtype_name__ = "NoDriver"

View File

@ -20,6 +20,7 @@ class StateManager(GObject.GObject):
}
__gproperties__ = {
'driver-running': (bool, 'Driver Running', 'Whether the driver is running', False, GObject.ParamFlags.READWRITE),
'follow-mode': (bool, 'Follow Mode', 'Whether the follow mode is enabled', False, GObject.ParamFlags.READWRITE),
'follow-threshold': (float, 'Follow Threshold', 'The follow threshold', 1.0, 45.0, 15.0, GObject.ParamFlags.READWRITE),
'widescreen-mode': (bool, 'Widescreen Mode', 'Whether widescreen mode is enabled', False, GObject.ParamFlags.READWRITE),
@ -53,6 +54,7 @@ class StateManager(GObject.GObject):
def __init__(self):
GObject.GObject.__init__(self)
self.ipc = XRDriverIPC.get_instance()
self.driver_running = False
self.connected_device_name = None
self.license_action_needed = False
self.license_action_needed_seconds = 0
@ -71,6 +73,8 @@ class StateManager(GObject.GObject):
def _refresh_state(self):
self.state = self.ipc.retrieve_driver_state()
self.set_property('driver-running', self.state['ui_view'].get('driver_running'))
new_device_name = StateManager.device_name(self.state)
if self.connected_device_name != new_device_name:
self.connected_device_name = new_device_name
@ -94,12 +98,14 @@ class StateManager(GObject.GObject):
elif self.license_present:
self.set_property('license-present', False)
self.set_property('follow-mode', self.state.get('breezy_desktop_smooth_follow_enabled'))
self.set_property('widescreen-mode', self.state.get('sbs_mode_enabled'))
self.set_property('follow-mode', self.state.get('breezy_desktop_smooth_follow_enabled', False))
self.set_property('widescreen-mode', self.state.get('sbs_mode_enabled', False))
if self.running: threading.Timer(1.0, self._refresh_state).start()
def do_set_property(self, prop, value):
if prop.name == 'driver-running':
self.driver_running = value
if prop.name == 'follow-mode':
self.follow_mode = value
if prop.name == 'widescreen-mode':
@ -112,6 +118,8 @@ class StateManager(GObject.GObject):
self.enabled_features = value
def do_get_property(self, prop):
if prop.name == 'driver-running':
return self.driver_running
if prop.name == 'follow-mode':
return self.follow_mode
if prop.name == 'widescreen-mode':

View File

@ -25,6 +25,7 @@ from .statemanager import StateManager
from .connecteddevice import ConnectedDevice
from .failedverification import FailedVerification
from .nodevice import NoDevice
from .nodriver import NoDriver
from .noextension import NoExtension
from .nolicense import NoLicense
from .verify import verify_installation
@ -49,6 +50,7 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
self.connected_device = ConnectedDevice()
self.failed_verification = FailedVerification()
self.no_device = NoDevice()
self.no_driver = NoDriver()
self.no_extension = NoExtension()
self.no_license = NoLicense()
@ -77,15 +79,17 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
if not verify_installation():
self.main_content.append(self.failed_verification)
if not self.state_manager.get_property('license-present'):
if not self.state_manager.driver_running:
self.main_content.append(self.no_driver)
elif not state_manager.connected_device_name:
self.main_content.append(self.no_device)
elif not self.state_manager.license_present:
self.main_content.append(self.no_license)
elif not ExtensionsManager.get_instance().is_installed():
self.main_content.append(self.no_extension)
elif state_manager.connected_device_name:
else:
self.main_content.append(self.connected_device)
self.connected_device.set_device_name(state_manager.connected_device_name)
else:
self.main_content.append(self.no_device)
def _on_license_button_clicked(self, widget):
dialog = LicenseDialog()