Skip to content

Commit

Permalink
fix: reimplement IsOnBookmark to fix #93
Browse files Browse the repository at this point in the history
The code changes in this commit improve the bookmark handling logic. Specifically, the `IsOnMenuBookmark` function has now been merged into `IsOnBookmark`, and the associated functions have been merged/removed as well. `IsOnBookmark` now directly recursively checks for `ROLE_SYSTEM_PUSHBUTTON` or `ROLE_SYSTEM_MENUITEM` under the `hwnd` of `Chrome_Widget_`, so it is no longer necessary to handle bookmarks on the bookmarks bar and bookmarks in bookmark folders with two separate functions.

The reimplemented function also resolves #93, as it avoids misjudgments caused by raw traversal of invisible nodes.

Co-authored-by: Ritchie1108 <[email protected]>
  • Loading branch information
Bush2021 and Ritchie1108 committed Jul 19, 2024
1 parent 2ff38f0 commit b204396
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 115 deletions.
116 changes: 37 additions & 79 deletions src/iaccessible.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,27 +221,6 @@ NodePtr GetTopContainerView(HWND hwnd) {
return top_container_view;
}

NodePtr GetMenuBarPane(HWND hwnd) {
NodePtr menu_bar_pane = nullptr;
wchar_t name[MAX_PATH];
if (GetClassName(hwnd, name, MAX_PATH) &&
wcsstr(name, L"Chrome_WidgetWin_") == name) {
NodePtr pacc_main_window = nullptr;
if (S_OK == AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
IID_PPV_ARGS(&pacc_main_window))) {
NodePtr menu_bar =
FindElementWithRole(pacc_main_window, ROLE_SYSTEM_MENUBAR);
if (menu_bar) {
menu_bar_pane = GetParentElement(menu_bar);
}
if (!menu_bar_pane) {
DebugLog(L"GetBookmarkView failed");
}
}
}
return menu_bar_pane;
}

// Gets the current number of tabs.
int GetTabCount(NodePtr top) {
NodePtr page_tab_list = FindElementWithRole(top, ROLE_SYSTEM_PAGETABLIST);
Expand Down Expand Up @@ -448,74 +427,53 @@ bool IsOnNewTab(NodePtr top) {
return IsNameNewTab(top) || IsDocNewTab();
}

// Whether the mouse is on a bookmark in the bookmark bar.
bool IsOnBookmark(NodePtr top, POINT pt) {
if (!top) {
// Whether the mouse is on a bookmark.
bool IsOnBookmark(HWND hwnd, POINT pt) {
wchar_t name[MAX_PATH];
if (!GetClassName(hwnd, name, MAX_PATH) ||
wcsstr(name, L"Chrome_WidgetWin_") != name) {
return false;
}
NodePtr pacc_main_window = nullptr;
if (S_OK != AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
IID_PPV_ARGS(&pacc_main_window))) {
return false;
}

bool flag = false;
TraversalAccessible(
top,
[&flag, &pt](NodePtr child) {
if (GetAccessibleRole(child) != ROLE_SYSTEM_PUSHBUTTON) {
return false;
}

GetAccessibleSize(child, [&flag, &pt, &child](RECT rect) {
if (!PtInRect(&rect, pt)) {
return;
TraversalAccessible(pacc_main_window, [&flag, &pt](NodePtr child) {
std::function<bool(NodePtr)> LambdaEnumChild =
[&pt, &flag, &LambdaEnumChild](NodePtr child) -> bool {
auto role = GetAccessibleRole(child);
if (role == ROLE_SYSTEM_PUSHBUTTON || role == ROLE_SYSTEM_MENUITEM) {
bool is_in_rect = false;
GetAccessibleSize(child, [&is_in_rect, &pt](const RECT& rect) {
if (PtInRect(&rect, pt)) {
is_in_rect = true;
}

});
if (is_in_rect) {
GetAccessibleDescription(child, [&flag](BSTR bstr) {
std::wstring_view bstr_view(bstr);
flag = bstr_view.find_first_of(L".:") != std::wstring_view::npos &&
bstr_view.substr(0, 11) != L"javascript:";
flag =
(bstr_view.find_first_of(L".:") != std::wstring_view::npos) &&
(bstr_view.substr(0, 11) != L"javascript:");
});
});

return flag;
},
true); // raw_traversal

return flag;
}

// Whether the mouse is on a bookmark in the menu bar (folder).
bool IsOnMenuBookmark(NodePtr top, POINT pt) {
NodePtr menu_bar = FindElementWithRole(top, ROLE_SYSTEM_MENUBAR);
if (!menu_bar) {
return false;
}

NodePtr menu_item = FindElementWithRole(menu_bar, ROLE_SYSTEM_MENUITEM);
if (!menu_item) {
return false;
}

NodePtr menu_bar_pane = GetParentElement(menu_item);
if (!menu_bar_pane) {
return false;
}

bool flag = false;
TraversalAccessible(menu_bar_pane, [&flag, &pt](NodePtr child) {
if (GetAccessibleRole(child) != ROLE_SYSTEM_MENUITEM) {
return false;
}

GetAccessibleSize(child, [&flag, &pt, &child](RECT rect) {
if (!PtInRect(&rect, pt)) {
return;
if (flag) {
return true; // Stop traversing if found.
}
}
}

GetAccessibleDescription(child, [&flag](BSTR bstr) {
std::wstring_view bstr_view(bstr);
flag = bstr_view.find_first_of(L".:") != std::wstring_view::npos &&
bstr_view.substr(0, 11) != L"javascript:";
});
});

// traverse the child nodes.
long child_count = 0;
if (S_OK == child->get_accChildCount(&child_count) && child_count > 0) {
TraversalAccessible(child, LambdaEnumChild, 0);
}
return flag;
};
// Start traversing.
TraversalAccessible(child, LambdaEnumChild, 0);
return flag;
});

Expand Down
39 changes: 3 additions & 36 deletions src/tabbookmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ int HandleMiddleClick(WPARAM wParam, PMOUSEHOOKSTRUCT pmouse) {
return 0;
}

// Open bookmarks in a new tab from the bookmark bar.
// Open bookmarks in a new tab.
bool HandleBookmark(WPARAM wParam, PMOUSEHOOKSTRUCT pmouse) {
if (wParam != WM_LBUTTONUP || IsPressed(VK_CONTROL) || IsPressed(VK_SHIFT) ||
config.is_bookmark_new_tab == "disabled") {
Expand All @@ -201,10 +201,10 @@ bool HandleBookmark(WPARAM wParam, PMOUSEHOOKSTRUCT pmouse) {
HWND hwnd = WindowFromPoint(pmouse->pt);
NodePtr top_container_view = GetTopContainerView(hwnd);

bool is_on_bookmark = IsOnBookmark(top_container_view, pmouse->pt);
bool is_on_bookmark = IsOnBookmark(hwnd, pmouse->pt);
bool is_on_new_tab = IsOnNewTab(top_container_view);

if (top_container_view && is_on_bookmark && !is_on_new_tab) {
if (is_on_bookmark && !is_on_new_tab) {
if (config.is_bookmark_new_tab == "foreground") {
SendKey(VK_MBUTTON, VK_SHIFT);
} else if (config.is_bookmark_new_tab == "background") {
Expand All @@ -216,35 +216,6 @@ bool HandleBookmark(WPARAM wParam, PMOUSEHOOKSTRUCT pmouse) {
return false;
}

// Open bookmarks in a new tab from a bookmark menu (folder).
bool HandleBookmarkMenu(WPARAM wParam, PMOUSEHOOKSTRUCT pmouse) {
if (wParam != WM_LBUTTONUP || IsPressed(VK_CONTROL) || IsPressed(VK_SHIFT) ||
config.is_bookmark_new_tab == "disabled") {
return false;
}

HWND hwnd_from_point = WindowFromPoint(pmouse->pt);
HWND hwnd_from_keyboard = GetFocus();
NodePtr top_container_view = GetTopContainerView(hwnd_from_keyboard);
NodePtr menu_bar_pane = GetMenuBarPane(hwnd_from_point);

bool is_on_menu_bookmark = IsOnMenuBookmark(menu_bar_pane, pmouse->pt);
bool is_on_new_tab = IsOnNewTab(top_container_view);

if (top_container_view && menu_bar_pane && is_on_menu_bookmark &&
!is_on_new_tab) {
if (config.is_bookmark_new_tab == "foreground") {
DebugLog(L"MButton + Shift");
SendKey(VK_MBUTTON, VK_SHIFT);
} else if (config.is_bookmark_new_tab == "background") {
SendKey(VK_MBUTTON);
}
return true;
}

return false;
}

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode != HC_ACTION) {
return CallNextHookEx(mouse_hook, nCode, wParam, lParam);
Expand Down Expand Up @@ -283,10 +254,6 @@ LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (HandleBookmark(wParam, pmouse)) {
return 1;
}

if (HandleBookmarkMenu(wParam, pmouse)) {
return 1;
}
} while (0);
return CallNextHookEx(mouse_hook, nCode, wParam, lParam);
}
Expand Down

0 comments on commit b204396

Please sign in to comment.