Skip to content

Commit

Permalink
Fixes for release 3.8 (#138)
Browse files Browse the repository at this point in the history
* Fix switching away from desktop window and photos app. Adds calculator app, #137
Add partial workaround for JetBrains PyCharm and WebStorm, #131

* Drop focus loop protection as it would seem floating windows are the ones that can't be focused, #80

* Update universal binary to v3.8.0

---------

Co-authored-by: Stefan Post <[email protected]>
  • Loading branch information
sbmpost and Stefan Post authored May 17, 2023
1 parent 1b341e2 commit 72c17a0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 25 deletions.
Binary file modified AutoRaise.dmg
Binary file not shown.
61 changes: 38 additions & 23 deletions AutoRaise.mm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <Carbon/Carbon.h>
#include <libproc.h>

#define AUTORAISE_VERSION "3.7"
#define AUTORAISE_VERSION "3.8"
#define STACK_THRESHOLD 20

#define __MAC_11_06_0 110600
Expand Down Expand Up @@ -88,9 +88,11 @@
// Above methods are undocumented and subjective to incompatible changes

#ifdef FOCUS_FIRST
static int raiseDelayCount = 0;
static pid_t lastFocusedWindow_pid;
static AXUIElementRef _lastFocusedWindow = NULL;
static CGWindowID lastFocusedWindow_id = 0;
static NSArray * mainWindowAppsWithoutTitle = @[@"Photos", @"Calculator"];
static NSArray * jetBrainsAppsRaisingOnFocus = @[@"IntelliJ IDEA", @"PyCharm", @"WebStorm"];
#endif

CFMachPortRef eventTap = NULL;
Expand All @@ -101,11 +103,9 @@
static AXUIElementRef _dock_app = NULL;
static NSArray * ignoreApps = NULL;
static NSArray * stayFocusedBundleIds = NULL;
static const NSString * IntelliJ = @"IntelliJ IDEA";
static const NSString * Dock = @"com.apple.dock";
static const NSString * Finder = @"com.apple.finder";
static const NSString * AssistiveControl = @"AssistiveControl";
static const NSString * Photos = @"Photos";
static const NSString * BartenderBar = @"Bartender Bar";
static const NSString * Launchpad = @"Launchpad";
static const NSString * XQuartz = @"XQuartz";
Expand All @@ -130,9 +130,6 @@
static int delayCount = 0;
static int pollMillis = 0;
static int disableKey = 0;
#ifdef FOCUS_FIRST
static int raiseDelayCount = 0;
#endif

//----------------------------------------yabai focus only methods------------------------------------------

Expand Down Expand Up @@ -519,7 +516,7 @@ inline bool desktop_window(AXUIElementRef _window) {
}

#ifdef FOCUS_FIRST
inline bool main_window(AXUIElementRef _window) {
inline bool main_window(AXUIElementRef _app, AXUIElementRef _window) {
bool main_window = false;
CFBooleanRef _result = NULL;
AXUIElementCopyAttributeValue(_window, kAXMainAttribute, (CFTypeRef *) &_result);
Expand All @@ -528,7 +525,11 @@ inline bool main_window(AXUIElementRef _window) {
CFRelease(_result);
}

main_window = main_window && !titleEquals(_window, @[NoTitle]);
main_window = main_window && (
!titleEquals(_window, @[NoTitle]) ||
titleEquals(_app, @[@"Finder"]) ||
titleEquals(_app, mainWindowAppsWithoutTitle));

if (verbose && !main_window) { NSLog(@"Not a main window"); }
return main_window;
}
Expand Down Expand Up @@ -975,13 +976,13 @@ void onTick() {
bool needs_raise = true;
AXUIElementRef _mouseWindowApp = AXUIElementCreateApplication(mouseWindow_pid);
#ifdef FOCUS_FIRST
bool app_main_window = false;
bool temporary_workaround_for_intellij_raising_its_subwindows_on_focus = false;
bool mouse_main_window_without_title = false;
bool temporary_workaround_for_jetbrains_apps_raising_subwindows_on_focus = false;
if (delayCount && raiseDelayCount != 1 && titleEquals(_mouseWindow, @[NoTitle])) {
if (!titleEquals(_mouseWindowApp, @[Photos])) {
if (!titleEquals(_mouseWindowApp, mainWindowAppsWithoutTitle)) {
needs_raise = false;
if (verbose) { NSLog(@"Excluding window"); }
} else { app_main_window = true; }
} else { mouse_main_window_without_title = true; }
} else
#endif
if (titleEquals(_mouseWindow, @[BartenderBar])) {
Expand All @@ -993,8 +994,8 @@ void onTick() {
if (verbose) { NSLog(@"Excluding app"); }
}
#ifdef FOCUS_FIRST
temporary_workaround_for_intellij_raising_its_subwindows_on_focus =
titleEquals(_mouseWindowApp, @[IntelliJ]);
temporary_workaround_for_jetbrains_apps_raising_subwindows_on_focus =
titleEquals(_mouseWindowApp, jetBrainsAppsRaisingOnFocus);
#endif
}
CFRelease(_mouseWindowApp);
Expand Down Expand Up @@ -1023,16 +1024,16 @@ void onTick() {
needs_raise = mouseWindow_id != focusedWindow_id;
#ifdef FOCUS_FIRST
if (delayCount && raiseDelayCount != 1) {
if (needs_raise) {
needs_raise = raiseTimes || mouseWindow_id != lastFocusedWindow_id;
} else { lastFocusedWindow_id = 0; }
if (raiseDelayCount) {
needs_raise = needs_raise && !contained_within(_focusedWindow, _mouseWindow);
} else {
if (temporary_workaround_for_intellij_raising_its_subwindows_on_focus) {
if (temporary_workaround_for_jetbrains_apps_raising_subwindows_on_focus) {
needs_raise = needs_raise && !contained_within(_focusedWindow, _mouseWindow);
}
needs_raise = needs_raise && (app_main_window || main_window(_focusedWindow));
needs_raise = needs_raise && (
mouse_main_window_without_title ||
main_window(_frontmostApp, _focusedWindow)
);
}
if (needs_raise) {
OSStatus error = GetProcessForPID(frontmost_pid, &focusedWindow_psn);
Expand Down Expand Up @@ -1065,12 +1066,26 @@ void onTick() {
if (delayCount && raiseDelayCount != 1) {
OSStatus error = GetProcessForPID(mouseWindow_pid, &mouseWindow_psn);
if (!error) {
window_manager_focus_window_without_raise(&mouseWindow_psn,
mouseWindow_id, _focusedWindow_psn, focusedWindow_id);
bool floating_window = false;
CFStringRef _element_sub_role = NULL;
AXUIElementCopyAttributeValue(
_mouseWindow,
kAXSubroleAttribute,
(CFTypeRef *) &_element_sub_role);
if (_element_sub_role) {
floating_window =
CFEqual(_element_sub_role, kAXFloatingWindowSubrole) ||
CFEqual(_element_sub_role, kAXSystemFloatingWindowSubrole);
CFRelease(_element_sub_role);
}
if (!floating_window) {
// TODO: method below seems unable to focus floating windows
window_manager_focus_window_without_raise(&mouseWindow_psn,
mouseWindow_id, _focusedWindow_psn, focusedWindow_id);
} else if (verbose) { NSLog(@"Unable to focus floating window"); }
if (_lastFocusedWindow) { CFRelease(_lastFocusedWindow); }
_lastFocusedWindow = _mouseWindow;
lastFocusedWindow_pid = mouseWindow_pid;
lastFocusedWindow_id = mouseWindow_id;
if (raiseDelayCount) { [workspaceWatcher windowFocused: _lastFocusedWindow]; }
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<key>CFBundleGetInfoString</key>
<string>Copyright © 2023 sbmpost</string>
<key>CFBundleShortVersionString</key>
<string>3.7</string>
<string>3.8</string>
<key>CFBundleIconFile</key>
<string>AutoRaise</string>
<key>CFBundleName</key>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ like so:

The output should look something like this:

v3.7 by sbmpost(c) 2023, usage:
v3.8 by sbmpost(c) 2023, usage:

AutoRaise
-pollMillis <20, 30, 40, 50, ...>
Expand Down

0 comments on commit 72c17a0

Please sign in to comment.