Workaround to stop Alt key state from sticking following cross-window interactions #1894

This is at best a temporary solution, need to find a better way to address this or rewrite the feature to not require global alt key state.

      // It's difficult to reliably detect when the user lets go of the alt key if they:
      // - start a drag and drag out of the app
      // - open a native context menu and release the alt key
      // - background the app and release the alt key
      //
      // As a workaround, automatically release the alt key after 3 seconds of inactivity.
      // This should be fine for all practical use as a modifer key and prevents it from
      // being indefinitely "stuck" in the on-state.
This commit is contained in:
Ben Gotow 2020-04-15 23:22:18 -05:00
parent a4bdb7679f
commit ee8c9c02aa
5 changed files with 44 additions and 19 deletions

View file

@ -41,15 +41,17 @@ class SearchMailboxPerspective extends MailboxPerspective {
<span>
{localized('No search results')}
{!inTrash && (
<a
className="btn"
style={{ fontWeight: 'normal' }}
onClick={() =>
Actions.searchQuerySubmitted(`${this.searchQuery} (in:trash OR in:spam)`)
}
>
{localized('Search messages in trash and spam')}
</a>
<div>
<a
className="btn"
style={{ fontWeight: 'normal' }}
onClick={() =>
Actions.searchQuerySubmitted(`${this.searchQuery} (in:trash OR in:spam)`)
}
>
{localized('Search messages in trash and spam')}
</a>
</div>
)}
</span>
);

View file

@ -108,20 +108,40 @@ export default class KeymapManager {
_bindingsCache: {};
_commandsCache: {};
_altKeyDown: boolean = false;
_altKeyTimer: NodeJS.Timeout = null;
EVENT_ALT_KEY_STATE_CHANGE = 'alt-key-state-change';
constructor({ configDirPath, resourcePath }) {
this.configDirPath = configDirPath;
this.resourcePath = resourcePath;
window.addEventListener('keydown', this.onCheckModifierState);
window.addEventListener('keyup', this.onCheckModifierState);
for (const event of ['keydown', 'keyup', 'click']) {
window.addEventListener(event, (e: KeyboardEvent) => this.onUpsertModifierState(e.altKey), {
capture: true,
passive: true,
});
}
}
onCheckModifierState = (e: KeyboardEvent) => {
if (this._altKeyDown !== e.altKey) {
this._altKeyDown = e.altKey;
onUpsertModifierState = (altKeyDown: boolean) => {
if (this._altKeyDown !== altKeyDown) {
this._altKeyDown = altKeyDown;
document.dispatchEvent(new CustomEvent(this.EVENT_ALT_KEY_STATE_CHANGE));
// It's difficult to reliably detect when the user lets go of the alt key if they:
// - start a drag and drag out of the app
// - open a native context menu and release the alt key
// - background the app and release the alt key
//
// As a workaround, automatically release the alt key after 3 seconds of inactivity.
// This should be fine for all practical use as a modifer key and prevents it from
// being indefinitely "stuck" in the on-state.
//
clearTimeout(this._altKeyTimer);
if (altKeyDown) {
this._altKeyTimer = setTimeout(() => this.onUpsertModifierState(false), 3 * 1000);
}
}
};

View file

@ -78,14 +78,10 @@ body.platform-win32 {
&:active {
cursor: default;
background: darken(@btn-default-bg-color, 9%);
color: @btn-default-text-color;
}
&:focus {
outline: none;
}
&:hover {
color: @btn-default-text-color;
}
font-size: @font-size-small;

View file

@ -34,6 +34,13 @@
font-size: 2em;
font-weight: @font-weight-thin;
text-align: center;
.btn {
color: @btn-default-text-color;
&:hover {
color: @btn-default-text-color;
}
}
}
}

@ -1 +1 @@
Subproject commit 171f7c247ab429d39c78f5cd935bb1c6053ef3ca
Subproject commit 95fbd9c8f42f9b73bcdc184ca31ba812c933f52b