diff --git a/L10n/en.template b/L10n/en.template index fcb3d4c6..ea83905b 100644 --- a/L10n/en.template +++ b/L10n/en.template @@ -82,6 +82,9 @@ /* [prefs.py:159] */ "OK" = "OK"; +/* Hotkey/Shortcut setting. [prefs.py:141] */ +"Only when Elite: Dangerous is the active app" = "Only when Elite: Dangerous is the active app"; + /* Shortcut settings button on OSX. [prefs.py:133] */ "Open System Preferences" = "Open System Preferences"; diff --git a/README.md b/README.md index dbb90d66..80f32a03 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,7 @@ Setup The first time that you run the app you are prompted for your username and password. This is the same username and password combination that you use to log into the Elite: Dangerous launcher, and is required so that the Frontier servers can send the app *your* data and the market data for the station that *you* are docked at. -You can also choose here: - -* What data to save (refer to the next section for details). -* Whether to set up a hotkey so you don't have to switch to the app in order to “Update”. (Note: The hotkey only activates when Elite: Dangerous is in the foreground). -* Whether to attach your Cmdr name or a [pseudo-anonymized](http://en.wikipedia.org/wiki/Pseudonymity) ID to the data. +You can also choose here what data to save (refer to the next section for details), whether to set up a hotkey so you don't have to switch to the app in order to “Update”, and whether to attach your Cmdr name or a [pseudo-anonymized](http://en.wikipedia.org/wiki/Pseudonymity) ID to the data. You are next prompted to authenticate with a “verification code”, which you will shortly receive by email from Frontier. Note that each “verification code” is one-time only - if you enter the code incorrectly or quit the app before diff --git a/hotkey.py b/hotkey.py index 12db6bae..0d8630b4 100644 --- a/hotkey.py +++ b/hotkey.py @@ -5,6 +5,8 @@ from os.path import dirname, join, normpath import sys from sys import platform +from config import config + if platform == 'darwin': import threading @@ -113,10 +115,12 @@ if platform == 'darwin': def _handler(self, event): # use event.charactersIgnoringModifiers to handle composing characters like Alt-e if (event.modifierFlags() & HotkeyMgr.MODIFIERMASK) == self.modifiers and ord(event.charactersIgnoringModifiers()[0]) == self.keycode: - # Only trigger if game client is front process - active = [x for x in NSWorkspace.sharedWorkspace().runningApplications() if x.isActive()] - if active and active[0] and active[0].bundleIdentifier() == 'uk.co.frontier.EliteDangerous': + if config.getint('hotkey_always'): self.activated = True + else: # Only trigger if game client is front process + active = [x for x in NSWorkspace.sharedWorkspace().runningApplications() if x.isActive()] + if active and active[0] and active[0].bundleIdentifier() == 'uk.co.frontier.EliteDangerous': + self.activated = True def acquire_start(self): self.acquire_state = HotkeyMgr.ACQUIRE_ACTIVE @@ -286,12 +290,15 @@ elif platform == 'win32': msg = MSG() while GetMessage(ctypes.byref(msg), None, 0, 0) != 0: if msg.message == WM_HOTKEY: - h = GetForegroundWindow() - if h: - l = GetWindowTextLength(h) + 1 - buf = ctypes.create_unicode_buffer(l) - if GetWindowText(h, buf, l) and buf.value.startswith('Elite - Dangerous'): - self.root.event_generate('<>', when="tail") + if config.getint('hotkey_always'): + self.root.event_generate('<>', when="tail") + else: # Only trigger if game client is front process + h = GetForegroundWindow() + if h: + l = GetWindowTextLength(h) + 1 + buf = ctypes.create_unicode_buffer(l) + if GetWindowText(h, buf, l) and buf.value.startswith('Elite - Dangerous'): + self.root.event_generate('<>', when="tail") elif msg.message == WM_SND_GOOD: winsound.PlaySound(self.snd_good, winsound.SND_MEMORY) # synchronous elif msg.message == WM_SND_BAD: diff --git a/prefs.py b/prefs.py index 8b51216b..387740f8 100644 --- a/prefs.py +++ b/prefs.py @@ -120,6 +120,7 @@ class PreferencesDialog(tk.Toplevel): if platform in ['darwin','win32']: self.hotkey_code = config.getint('hotkey_code') self.hotkey_mods = config.getint('hotkey_mods') + self.hotkey_only = tk.IntVar(value = not config.getint('hotkey_always')) self.hotkey_play = tk.IntVar(value = not config.getint('hotkey_mute')) hotkeyframe = ttk.LabelFrame(frame, text=platform == 'darwin' and _('Keyboard shortcut') or # Section heading in settings on OSX _('Hotkey')) # Section heading in settings on Windows @@ -137,17 +138,19 @@ class PreferencesDialog(tk.Toplevel): self.hotkey_text.bind('', self.hotkeystart) self.hotkey_text.bind('', self.hotkeyend) self.hotkey_text.grid(row=0, padx=5, pady=5, sticky=tk.NSEW) + self.hotkey_only_btn = ttk.Checkbutton(hotkeyframe, text=_('Only when Elite: Dangerous is the active app'), variable=self.hotkey_only, state = self.hotkey_code and tk.NORMAL or tk.DISABLED) # Hotkey/Shortcut setting + self.hotkey_only_btn.grid(row=1, columnspan=2, padx=5, sticky=tk.W) self.hotkey_play_btn = ttk.Checkbutton(hotkeyframe, text=_('Play sound'), variable=self.hotkey_play, state = self.hotkey_code and tk.NORMAL or tk.DISABLED) # Hotkey/Shortcut setting - self.hotkey_play_btn.grid(row=0, column=1, padx=(10,0), pady=5, sticky=tk.NSEW) + self.hotkey_play_btn.grid(row=2, columnspan=2, padx=5, sticky=tk.W) privacyframe = ttk.LabelFrame(frame, text=_('Privacy')) # Section heading in settings privacyframe.grid(padx=10, pady=10, sticky=tk.NSEW) privacyframe.columnconfigure(0, weight=1) self.out_anon= tk.IntVar(value = config.getint('anonymous') and 1) - ttk.Label(privacyframe, text=_('How do you want to be identified in the saved data')).grid(row=0, columnspan=2, padx=5, pady=3, sticky=tk.W) + ttk.Label(privacyframe, text=_('How do you want to be identified in the saved data')).grid(row=0, columnspan=2, padx=5, sticky=tk.W) ttk.Radiobutton(privacyframe, text=_('Cmdr name'), variable=self.out_anon, value=0).grid(padx=5, sticky=tk.W) # Privacy setting - ttk.Radiobutton(privacyframe, text=_('Pseudo-anonymized ID'), variable=self.out_anon, value=1).grid(padx=5, pady=3, sticky=tk.W) # Privacy setting + ttk.Radiobutton(privacyframe, text=_('Pseudo-anonymized ID'), variable=self.out_anon, value=1).grid(padx=5, sticky=tk.W) # Privacy setting if platform=='darwin': self.protocol("WM_DELETE_WINDOW", self.apply) # close button applies changes @@ -225,19 +228,22 @@ class PreferencesDialog(tk.Toplevel): if hotkey_code: # done (self.hotkey_code, self.hotkey_mods) = (hotkey_code, hotkey_mods) + self.hotkey_only_btn['state'] = tk.NORMAL self.hotkey_play_btn['state'] = tk.NORMAL - self.hotkey_play_btn.focus() # move to next widget - calls hotkeyend() implicitly + self.hotkey_only_btn.focus() # move to next widget - calls hotkeyend() implicitly else: if good is None: # clear (self.hotkey_code, self.hotkey_mods) = (0, 0) event.widget.delete(0, tk.END) if self.hotkey_code: event.widget.insert(0, hotkeymgr.display(self.hotkey_code, self.hotkey_mods)) + self.hotkey_only_btn['state'] = tk.NORMAL self.hotkey_play_btn['state'] = tk.NORMAL else: event.widget.insert(0, _('none')) # No hotkey/shortcut currently defined + self.hotkey_only_btn['state'] = tk.DISABLED self.hotkey_play_btn['state'] = tk.DISABLED - self.hotkey_play_btn.focus() # move to next widget - calls hotkeyend() implicitly + self.hotkey_only_btn.focus() # move to next widget - calls hotkeyend() implicitly return('break') # stops further processing - insertion, Tab traversal etc @@ -250,6 +256,7 @@ class PreferencesDialog(tk.Toplevel): if platform in ['darwin','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())) config.set('hotkey_mute', int(not self.hotkey_play.get())) config.set('anonymous', self.out_anon.get()) self._destroy()