From 989fe9f0471ee55c589a79c47bbe5eb22d321177 Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Thu, 16 Jun 2022 19:07:32 -0700 Subject: [PATCH 1/2] Add workaround in Open Shell for S0 LOW POWER IDLE If the system supports that power state Open Shell can't enter sleep mode. The workaround removes the standard sleep option from the list and adds a new sleep button above the shutdown button that just turns the monitor off. Addresses issue #719 --- scripts/wk/cfg/setup.py | 52 ++++++++++++++++++++++++++++++++++++++++- scripts/wk/setup/win.py | 23 +++++++++++++++++- scripts/wk/std.py | 3 +-- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/scripts/wk/cfg/setup.py b/scripts/wk/cfg/setup.py index 7a6d975e..28ac5154 100644 --- a/scripts/wk/cfg/setup.py +++ b/scripts/wk/cfg/setup.py @@ -98,7 +98,7 @@ REG_OPEN_SHELL_SETTINGS = { ( 'SkinOptionsW7', [ - # NOTE: Seems to need all options specified to work? + # NOTE: All options need to be specified to work 'DARK_MAIN=1', 'METRO_MAIN=0', 'LIGHT_MAIN=0', 'AUTOMODE_MAIN=0', 'DARK_SUBMENU=0', 'METRO_SUBMENU=0', 'LIGHT_SUBMENU=0', 'AUTOMODE_SUBMENU=1', 'SUBMENU_SEPARATORS=1', 'DARK_SEARCH=0', 'METRO_SEARCH=0', 'LIGHT_SEARCH=1', @@ -121,6 +121,56 @@ REG_OPEN_SHELL_SETTINGS = { ), }, } +REG_OPEN_SHELL_LOW_POWER_IDLE = { + 'HKCU': { + r'Software\OpenShell\StartMenu': ( + ( + 'CSettingsDlg', + b'h\x02\x00\x00\xa7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\r\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00', + 'BINARY', + ), + ( + 'CEditMenuDlg7', + b'\xde\x02\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + 'BINARY', + ), + ), + r'Software\OpenShell\StartMenu\Settings': ( + ('ShutdownW7', 'switch_user, logoff, lock, restart, hibernate', 'SZ'), + ( + 'MenuItems7', + [ + 'Item1.Command=user_files', 'Item1.Settings=NOEXPAND', + 'Item2.Command=user_documents', 'Item2.Settings=NOEXPAND', + 'Item3.Command=user_pictures', 'Item3.Settings=NOEXPAND', + 'Item4.Command=user_music', 'Item4.Settings=NOEXPAND', + 'Item5.Command=user_videos', 'Item5.Settings=ITEM_DISABLED', + 'Item6.Command=downloads', 'Item6.Settings=ITEM_DISABLED', + 'Item7.Command=homegroup', 'Item7.Settings=ITEM_DISABLED', + 'Item8.Command=separator', + 'Item9.Command=games', 'Item9.Settings=TRACK_RECENT|NOEXPAND|ITEM_DISABLED', + 'Item10.Command=favorites', 'Item10.Settings=ITEM_DISABLED', + 'Item11.Command=recent_documents', + 'Item12.Command=computer', 'Item12.Settings=NOEXPAND', + 'Item13.Command=network', 'Item13.Settings=ITEM_DISABLED', + 'Item14.Command=network_connections', 'Item14.Settings=ITEM_DISABLED', + 'Item15.Command=separator', + 'Item16.Command=control_panel', 'Item16.Settings=TRACK_RECENT', + 'Item17.Command=pc_settings', 'Item17.Settings=TRACK_RECENT', + 'Item18.Command=admin', 'Item18.Settings=TRACK_RECENT|ITEM_DISABLED', + 'Item19.Command=devices', 'Item19.Settings=NOEXPAND', + 'Item20.Command=defaults', + 'Item21.Command=help', + 'Item22.Command=run', + 'Item23.Command=monitor_off', 'Item23.Label=Sleep', 'Item23.Settings=NOEXPAND', + 'Item24.Command=apps', 'Item24.Settings=ITEM_DISABLED', + 'Item25.Command=windows_security', + ], + 'MULTI_SZ', + ), + ), + }, + } UBLOCK_ORIGIN_URLS = { 'Google Chrome': 'https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm', 'Microsoft Edge': 'https://microsoftedge.microsoft.com/addons/detail/ublock-origin/odfafepnkmbhccpbejgmiehpchacaeak', diff --git a/scripts/wk/setup/win.py b/scripts/wk/setup/win.py index 1b727d25..cb50e3ca 100644 --- a/scripts/wk/setup/win.py +++ b/scripts/wk/setup/win.py @@ -16,6 +16,7 @@ from wk.cfg.setup import ( REG_CHROME_UBLOCK_ORIGIN, REG_WINDOWS_EXPLORER, REG_OPEN_SHELL_SETTINGS, + REG_OPEN_SHELL_LOW_POWER_IDLE, UBLOCK_ORIGIN_URLS, ) from wk.exe import kill_procs, run_program, popen_program @@ -424,7 +425,7 @@ def auto_config_explorer(): def auto_config_open_shell(): """Configure Open Shell.""" - TRY_PRINT.run('Open Shell...', reg_write_settings, REG_OPEN_SHELL_SETTINGS) + TRY_PRINT.run('Open Shell...', config_open_shell) def auto_export_aida64_report(): @@ -539,6 +540,26 @@ def config_explorer(): popen_program(['explorer.exe']) +def config_open_shell(): + """Configure Open Shell.""" + has_low_power_idle = False + + # Check if the system supports S0 Low Power Idle + proc = run_program(['powercfg', '/AvailableSleepStates'], check=False) + for line in proc.stdout.splitlines(): + if 'Low Power Idle' in line: + # NOTE: This is safe since we break before the listed unsupported states + has_low_power_idle = True + break + if line.startswith('The following sleep states are not available'): + break + + # Apply registry settings + reg_write_settings(REG_OPEN_SHELL_SETTINGS) + if has_low_power_idle: + reg_write_settings(REG_OPEN_SHELL_LOW_POWER_IDLE) + + def disable_chrome_notifications(): """Disable notifications in Google Chrome.""" defaults_key = 'default_content_setting_values' diff --git a/scripts/wk/std.py b/scripts/wk/std.py index f86da901..793a5319 100644 --- a/scripts/wk/std.py +++ b/scripts/wk/std.py @@ -134,7 +134,7 @@ class Menu(): def _get_display_name( self, name, details, index=None, no_checkboxes=True, setting_item=False): - # pylint: disable=no-self-use,too-many-arguments + # pylint: disable=too-many-arguments """Format display name based on details and args, returns str.""" disabled = details.get('Disabled', False) if setting_item and not details['Selected']: @@ -503,7 +503,6 @@ class TryAndPrint(): @cache def _get_exception(self, name): - # pylint: disable=no-self-use """Get exception by name, returns exception object. [Doctest] From 9e874f80348bd355469579fc72406f2aff74bb12 Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Fri, 24 Jun 2022 10:36:10 -0700 Subject: [PATCH 2/2] Fix bug locking ddrescue-tui to pass Read-Skip --- scripts/wk/clone/ddrescue.py | 44 ++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/scripts/wk/clone/ddrescue.py b/scripts/wk/clone/ddrescue.py index a5f4676d..4ae3d988 100644 --- a/scripts/wk/clone/ddrescue.py +++ b/scripts/wk/clone/ddrescue.py @@ -250,28 +250,34 @@ class BlockPair(): self.map_data.update(data) def pass_complete(self, pass_name): - """Check if pass_num is complete based on map data, returns bool.""" - complete = False - pending_size = 0 + """Check if pass_name is complete based on map data, returns bool.""" + pending_size = self.map_data['non-tried'] - # Check map data + # Full recovery if self.map_data.get('full recovery', False): - complete = True - elif 'non-tried' not in self.map_data: - # Assuming recovery has not been attempted yet - complete = False - else: - # Check that current and previous passes are complete - pending_size = self.map_data['non-tried'] - if pass_name in ('trim', 'scrape'): - pending_size += self.map_data['non-trimmed'] - if pass_name == 'scrape': - pending_size += self.map_data['non-scraped'] - if pending_size == 0: - complete = True + return True - # Done - return complete + # New recovery + if 'non-tried' not in self.map_data: + return False + + # Initial read skip pass + if pass_name == 'read-skip': + pass_threshold = cfg.ddrescue.AUTO_PASS_THRESHOLDS[pass_name] + if self.get_percent_recovered() >= pass_threshold: + return True + + # Recovery in progress + if pass_name in ('trim', 'scrape'): + pending_size += self.map_data['non-trimmed'] + if pass_name == 'scrape': + pending_size += self.map_data['non-scraped'] + if pending_size == 0: + # This is true when the previous and current passes are complete + return True + + # This should never be reached + return False def safety_check(self): """Run safety check and abort if necessary."""