Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2186] Refine macOS Removal #2200

Closed
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[2186] Cull Prefs
Rixxan committed Apr 12, 2024
commit 228be5c3ac5bd269894d2c2504cbc88599488914
205 changes: 43 additions & 162 deletions prefs.py
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@

import myNotebook as nb # noqa: N813
import plug
from config import applongname, appversion_nobuild, config
from config import appversion_nobuild, config
from EDMCLogging import edmclogger, get_main_logger
from constants import appname
from hotkey import hotkeymgr
@@ -49,9 +49,6 @@ def help_open_log_folder() -> None:
if sys.platform.startswith('win'):
# On Windows, use the "start" command to open the folder
system(f'start "" "{logfile_loc}"')
elif sys.platform.startswith('darwin'):
# On macOS, use the "open" command to open the folder
system(f'open "{logfile_loc}"')
elif sys.platform.startswith('linux'):
# On Linux, use the "xdg-open" command to open the folder
system(f'xdg-open "{logfile_loc}"')
@@ -172,32 +169,7 @@ def __exit__(
return None


if sys.platform == 'darwin':
import objc # type: ignore
from Foundation import NSFileManager # type: ignore
try:
from ApplicationServices import ( # type: ignore
AXIsProcessTrusted, AXIsProcessTrustedWithOptions, kAXTrustedCheckOptionPrompt
)

except ImportError:
HIServices = objc.loadBundle(
'HIServices',
globals(),
'/System/Library/Frameworks/ApplicationServices.framework/Frameworks/HIServices.framework'
)

objc.loadBundleFunctions(
HIServices,
globals(),
[('AXIsProcessTrusted', 'B'), ('AXIsProcessTrustedWithOptions', 'B@')]
)

objc.loadBundleVariables(HIServices, globals(), [('kAXTrustedCheckOptionPrompt', '@^{__CFString=}')])

was_accessible_at_launch = AXIsProcessTrusted() # type: ignore

elif sys.platform == 'win32':
if sys.platform == 'win32':
import ctypes
import winreg
from ctypes.wintypes import HINSTANCE, HWND, LPCWSTR, LPWSTR, MAX_PATH, POINT, RECT, SIZE, UINT
@@ -251,30 +223,21 @@ def __init__(self, parent: tk.Tk, callback: Optional[Callable]):

self.parent = parent
self.callback = callback
if sys.platform == 'darwin':
# LANG: File > Preferences menu entry for macOS
self.title(_('Preferences'))

else:
# LANG: File > Settings (macOS)
self.title(_('Settings'))
# LANG: File > Settings (macOS)
self.title(_('Settings'))

if parent.winfo_viewable():
self.transient(parent)

# position over parent
if sys.platform != 'darwin' or parent.winfo_rooty() > 0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7
# TODO this is fixed supposedly.
self.geometry(f'+{parent.winfo_rootx()}+{parent.winfo_rooty()}')
# http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7
# TODO this is fixed supposedly.
self.geometry(f'+{parent.winfo_rootx()}+{parent.winfo_rooty()}')

# remove decoration
if sys.platform == 'win32':
self.attributes('-toolwindow', tk.TRUE)

elif sys.platform == 'darwin':
# http://wiki.tcl.tk/13428
parent.call('tk::unsupported::MacWindowStyle', 'style', self, 'utility')

self.resizable(tk.FALSE, tk.FALSE)

self.cmdr: str | bool | None = False # Note if Cmdr changes in the Journal
@@ -302,19 +265,15 @@ def __init__(self, parent: tk.Tk, callback: Optional[Callable]):
self.__setup_appearance_tab(notebook)
self.__setup_plugin_tab(notebook)

if sys.platform == 'darwin':
self.protocol("WM_DELETE_WINDOW", self.apply) # close button applies changes

else:
buttonframe = ttk.Frame(frame)
buttonframe.grid(padx=self.PADX, pady=self.PADX, sticky=tk.NSEW)
buttonframe.columnconfigure(0, weight=1)
ttk.Label(buttonframe).grid(row=0, column=0) # spacer
# LANG: 'OK' button on Settings/Preferences window
button = ttk.Button(buttonframe, text=_('OK'), command=self.apply)
button.grid(row=0, column=1, sticky=tk.E)
button.bind("<Return>", lambda event: self.apply())
self.protocol("WM_DELETE_WINDOW", self._destroy)
buttonframe = ttk.Frame(frame)
buttonframe.grid(padx=self.PADX, pady=self.PADX, sticky=tk.NSEW)
buttonframe.columnconfigure(0, weight=1)
ttk.Label(buttonframe).grid(row=0, column=0) # spacer
# LANG: 'OK' button on Settings/Preferences window
button = ttk.Button(buttonframe, text=_('OK'), command=self.apply)
button.grid(row=0, column=1, sticky=tk.E)
button.bind("<Return>", lambda event: self.apply())
self.protocol("WM_DELETE_WINDOW", self._destroy)

# FIXME: Why are these being called when *creating* the Settings window?
# Selectively disable buttons depending on output settings
@@ -326,7 +285,7 @@ def __init__(self, parent: tk.Tk, callback: Optional[Callable]):

# wait for window to appear on screen before calling grab_set
self.parent.update_idletasks()
self.parent.wm_attributes('-topmost', 0) # needed for dialog to appear ontop of parent on OSX & Linux
self.parent.wm_attributes('-topmost', 0) # needed for dialog to appear ontop of parent on Linux
self.wait_visibility()
self.grab_set()

@@ -402,16 +361,12 @@ def __setup_output_tab(self, root_notebook: ttk.Notebook) -> None:
# Type ignored due to incorrect type annotation. a 2 tuple does padding for each side
self.outdir_label.grid(padx=self.PADX, pady=self.PADY, sticky=tk.W, row=row.get()) # type: ignore

self.outdir_entry = nb.Entry(output_frame, takefocus=False)
self.outdir_entry = ttk.Entry(output_frame, takefocus=False)
self.outdir_entry.grid(columnspan=2, padx=self.PADX, pady=self.BOXY, sticky=tk.EW, row=row.get())

if sys.platform == 'darwin':
text = (_('Change...')) # LANG: macOS Preferences - files location selection button

else:
text = (_('Browse...')) # LANG: NOT-macOS Settings - files location selection button
text = _('Browse...') # LANG: NOT-macOS Settings - files location selection button

self.outbutton = nb.Button(
self.outbutton = ttk.Button(
output_frame,
text=text,
# Technically this is different from the label in Settings > Output, as *this* is used
@@ -421,8 +376,6 @@ def __setup_output_tab(self, root_notebook: ttk.Notebook) -> None:
)
self.outbutton.grid(column=1, padx=self.PADX, pady=self.PADY, sticky=tk.EW, row=row.get())

nb.Frame(output_frame).grid(row=row.get()) # bottom spacer # TODO: does nothing?

# LANG: Label for 'Output' Settings/Preferences tab
root_notebook.add(output_frame, text=_('Output')) # Tab heading in settings

@@ -444,7 +397,7 @@ def __setup_config_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001
logdir = default

self.logdir.set(logdir)
self.logdir_entry = nb.Entry(config_frame, takefocus=False)
self.logdir_entry = ttk.Entry(config_frame, takefocus=False)

# Location of the Journal files
nb.Label(
@@ -455,14 +408,10 @@ def __setup_config_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001

self.logdir_entry.grid(columnspan=4, padx=self.PADX, pady=self.BOXY, sticky=tk.EW, row=row.get())

if sys.platform == 'darwin':
text = (_('Change...')) # LANG: macOS Preferences - files location selection button

else:
text = (_('Browse...')) # LANG: NOT-macOS Setting - files location selection button
text = _('Browse...') # LANG: NOT-macOS Setting - files location selection button

with row as cur_row:
self.logbutton = nb.Button(
self.logbutton = ttk.Button(
config_frame,
text=text,
# LANG: Settings > Configuration - Label for Journal files location
@@ -472,7 +421,7 @@ def __setup_config_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001

if config.default_journal_dir_path:
# Appearance theme and language setting
nb.Button(
ttk.Button(
config_frame,
# LANG: Settings > Configuration - Label on 'reset journal files location to default' button
text=_('Default'),
@@ -499,7 +448,7 @@ def __setup_config_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001
variable=self.capi_fleetcarrier
).grid(columnspan=4, padx=self.BUTTONX, pady=self.PADY, sticky=tk.W, row=row.get())

if sys.platform in ('darwin', 'win32'):
if sys.platform == 'win32':
ttk.Separator(config_frame, orient=tk.HORIZONTAL).grid(
columnspan=4, padx=self.PADX, pady=self.SEPY, sticky=tk.EW, row=row.get()
)
@@ -511,49 +460,21 @@ def __setup_config_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001
with row as cur_row:
nb.Label(
config_frame,
text=_('Keyboard shortcut') if # LANG: Hotkey/Shortcut settings prompt on OSX
sys.platform == 'darwin' else
_('Hotkey') # LANG: Hotkey/Shortcut settings prompt on Windows
text=_('Hotkey') # LANG: Hotkey/Shortcut settings prompt on Windows
).grid(padx=self.PADX, pady=self.PADY, sticky=tk.W, row=cur_row)

if sys.platform == 'darwin' and not was_accessible_at_launch:
if AXIsProcessTrusted():
# Shortcut settings prompt on OSX
nb.Label(
config_frame,
# LANG: macOS Preferences > Configuration - restart the app message
text=_('Re-start {APP} to use shortcuts').format(APP=applongname),
foreground='firebrick'
).grid(padx=self.PADX, pady=self.PADY, sticky=tk.W, row=cur_row)

else:
# Shortcut settings prompt on OSX
nb.Label(
config_frame,
# LANG: macOS - Configuration - need to grant the app permission for keyboard shortcuts
text=_('{APP} needs permission to use shortcuts').format(APP=applongname),
foreground='firebrick'
).grid(columnspan=4, padx=self.PADX, pady=self.PADY, sticky=tk.W, row=cur_row)

# LANG: Shortcut settings button on OSX
nb.Button(config_frame, text=_('Open System Preferences'), command=self.enableshortcuts).grid(
padx=self.PADX, pady=self.BOXY, sticky=tk.E, row=cur_row
)

else:
self.hotkey_text = nb.Entry(config_frame, width=(
20 if sys.platform == 'darwin' else 30), justify=tk.CENTER)
self.hotkey_text.insert(
0,
# No hotkey/shortcut currently defined
# TODO: display Only shows up on darwin or windows
# LANG: No hotkey/shortcut set
hotkeymgr.display(self.hotkey_code, self.hotkey_mods) if self.hotkey_code else _('None')
)
self.hotkey_text = ttk.Entry(config_frame, width=30, justify=tk.CENTER)
self.hotkey_text.insert(
0,
# No hotkey/shortcut currently defined
# TODO: display Only shows up on windows
# LANG: No hotkey/shortcut set
hotkeymgr.display(self.hotkey_code, self.hotkey_mods) if self.hotkey_code else _('None')
)

self.hotkey_text.bind('<FocusIn>', self.hotkeystart)
self.hotkey_text.bind('<FocusOut>', self.hotkeyend)
self.hotkey_text.grid(column=1, columnspan=2, pady=self.BOXY, sticky=tk.W, row=cur_row)
self.hotkey_text.bind('<FocusIn>', self.hotkeystart)
self.hotkey_text.bind('<FocusOut>', self.hotkeyend)
self.hotkey_text.grid(column=1, columnspan=2, pady=self.BOXY, sticky=tk.W, row=cur_row)

# Hotkey/Shortcut setting
self.hotkey_only_btn = nb.Checkbutton(
@@ -700,7 +621,7 @@ def __setup_config_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001
self.loglevel_dropdown.configure(width=15)
self.loglevel_dropdown.grid(column=1, pady=self.BOXY, sticky=tk.W, row=cur_row)

nb.Button(
ttk.Button(
config_frame,
# LANG: Label on button used to open a filesystem folder
text=_('Open Log Folder'), # Button that opens a folder in Explorer/Finder
@@ -803,7 +724,7 @@ def __setup_appearance_tab(self, notebook: ttk.Notebook) -> None:
self.theme_label_0.grid(padx=self.PADX, pady=self.PADY, sticky=tk.W, row=cur_row)

# Main window
self.theme_button_0 = nb.ColoredButton(
self.theme_button_0 = tk.Button(
appearance_frame,
# LANG: Appearance - Example 'Normal' text
text=_('Station'),
@@ -816,7 +737,7 @@ def __setup_appearance_tab(self, notebook: ttk.Notebook) -> None:
with row as cur_row:
self.theme_label_1 = nb.Label(appearance_frame, text=self.theme_prompts[1])
self.theme_label_1.grid(padx=self.PADX, pady=self.PADY, sticky=tk.W, row=cur_row)
self.theme_button_1 = nb.ColoredButton(
self.theme_button_1 = tk.Button(
appearance_frame,
text=' Hutton Orbital ', # Do not translate
background='grey4',
@@ -947,7 +868,7 @@ def __setup_plugin_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001
padx=self.PADX, pady=self.PADY, sticky=tk.W, row=row.get()
)

plugdirentry = nb.Entry(plugins_frame, justify=tk.LEFT)
plugdirentry = ttk.Entry(plugins_frame, justify=tk.LEFT)
self.displaypath(plugdir, plugdirentry)
plugdirentry.grid(columnspan=2, padx=self.PADX, pady=self.BOXY, sticky=tk.EW, row=row.get())

@@ -959,7 +880,7 @@ def __setup_plugin_tab(self, notebook: ttk.Notebook) -> None: # noqa: CCR001
text=_("Tip: You can disable a plugin by{CR}adding '{EXT}' to its folder name").format(EXT='.disabled')
).grid(columnspan=2, padx=self.PADX, pady=self.PADY, sticky=tk.EW, row=cur_row)

nb.Button(
ttk.Button(
plugins_frame,
# LANG: Label on button used to open a filesystem folder
text=_('Open'), # Button that opens a folder in Explorer/Finder
@@ -1070,14 +991,6 @@ def cmdrchanged(self, event=None):
def tabchanged(self, event: tk.Event) -> None:
"""Handle preferences active tab changing."""
self.outvarchanged()
if sys.platform == 'darwin':
# Hack to recompute size so that buttons show up under Mojave
notebook = event.widget
frame = self.nametowidget(notebook.winfo_parent())
temp = nb.Label(frame)
temp.grid()
temp.update_idletasks()
temp.destroy()

def outvarchanged(self, event: Optional[tk.Event] = None) -> None:
"""Handle Output tab variable changes."""
@@ -1139,16 +1052,6 @@ def displaypath(self, pathvar: tk.StringVar, entryfield: tk.Entry) -> None:
entryfield.insert(0, '\\'.join(display))

# None if path doesn't exist
elif sys.platform == 'darwin' and NSFileManager.defaultManager().componentsToDisplayForPath_(pathvar.get()):
if pathvar.get().startswith(config.home):
display = ['~'] + NSFileManager.defaultManager().componentsToDisplayForPath_(pathvar.get())[
len(NSFileManager.defaultManager().componentsToDisplayForPath_(config.home)):
]

else:
display = NSFileManager.defaultManager().componentsToDisplayForPath_(pathvar.get())

entryfield.insert(0, '/'.join(display))
else:
if pathvar.get().startswith(config.home):
entryfield.insert(0, '~' + pathvar.get()[len(config.home):])
@@ -1288,7 +1191,7 @@ def apply(self) -> None:

config.set('capi_fleetcarrier', self.capi_fleetcarrier.get())

if sys.platform in ('darwin', 'win32'):
if sys.platform == 'win32':
config.set('hotkey_code', self.hotkey_code)
config.set('hotkey_mods', self.hotkey_mods)
config.set('hotkey_always', int(not self.hotkey_only.get()))
@@ -1333,25 +1236,3 @@ def _destroy(self) -> None:

self.parent.wm_attributes('-topmost', 1 if config.get_int('always_ontop') else 0)
self.destroy()

if sys.platform == 'darwin':
def enableshortcuts(self) -> None:
"""Set up macOS preferences shortcut."""
self.apply()
# popup System Preferences dialog
try:
# http://stackoverflow.com/questions/6652598/cocoa-button-opens-a-system-preference-page/6658201
from ScriptingBridge import SBApplication # type: ignore
sysprefs = 'com.apple.systempreferences'
prefs = SBApplication.applicationWithBundleIdentifier_(sysprefs)
pane = [x for x in prefs.panes() if x.id() == 'com.apple.preference.security'][0]
prefs.setCurrentPane_(pane)
anchor = [x for x in pane.anchors() if x.name() == 'Privacy_Accessibility'][0]
anchor.reveal()
prefs.activate()

except Exception:
AXIsProcessTrustedWithOptions({kAXTrustedCheckOptionPrompt: True})

if not config.shutting_down:
self.parent.event_generate('<<Quit>>', when="tail")