Skip to content

Commit 3d64ecc

Browse files
committed
fix: fix static state contamination in IsNeedKeep
1 parent 4b5e133 commit 3d64ecc

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

src/tabbookmark.cc

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,30 @@ namespace {
1212
constexpr UINT kDefaultDpi = 96;
1313
POINT lbutton_down_point = {-1, -1};
1414

15+
enum class KeepTabTrigger {
16+
kRightClick = 0,
17+
kMiddleClick,
18+
kCloseButton,
19+
kKeyboardShortcut,
20+
kCount,
21+
};
22+
1523
// This implements tick fault tolerance to prevent users from directly closing
1624
// the window when they click too fast. Also uses pre-computed `tab_count` to
1725
// avoid redundant `FindPageTabPane` traversal.
18-
// TODO: fix the static state contamination across mouse and keyboard handlers.
19-
bool IsNeedKeep(int tab_count) {
26+
bool IsNeedKeep(int tab_count, KeepTabTrigger trigger) {
2027
// `tab_count` will be 0 if `config.IsKeepLastTab()` is false.
2128
if (tab_count == 0) {
2229
return false;
2330
}
2431

2532
bool keep_tab = (tab_count == 1);
26-
static auto last_closing_tab_tick = GetTickCount64();
27-
auto tick = GetTickCount64() - last_closing_tab_tick;
28-
last_closing_tab_tick = GetTickCount64();
33+
static ULONGLONG
34+
last_closing_tab_ticks[static_cast<int>(KeepTabTrigger::kCount)] = {};
35+
const int trigger_index = static_cast<int>(trigger);
36+
const ULONGLONG now = GetTickCount64();
37+
const ULONGLONG tick = now - last_closing_tab_ticks[trigger_index];
38+
last_closing_tab_ticks[trigger_index] = now;
2939
if (tick > 50 && tick <= 250 && tab_count == 2) {
3040
keep_tab = true;
3141
}
@@ -159,7 +169,7 @@ bool HandleRightClick(const MOUSEHOOKSTRUCT* pmouse) {
159169
if (!tab) {
160170
return false;
161171
}
162-
if (IsNeedKeep(tab_count)) {
172+
if (IsNeedKeep(tab_count, KeepTabTrigger::kRightClick)) {
163173
ExecuteCommand(IDC_NEW_TAB, hwnd);
164174
ExecuteCommand(IDC_WINDOW_CLOSE_OTHER_TABS, hwnd);
165175
} else {
@@ -185,7 +195,7 @@ bool HandleMiddleClick(const MOUSEHOOKSTRUCT* pmouse) {
185195

186196
const auto [tab, tab_count] =
187197
GetTabInfo(top_container_view, pt, config.IsKeepLastTab());
188-
if (tab && IsNeedKeep(tab_count)) {
198+
if (tab && IsNeedKeep(tab_count, KeepTabTrigger::kMiddleClick)) {
189199
ExecuteCommand(IDC_NEW_TAB, hwnd);
190200
ExecuteCommand(IDC_WINDOW_CLOSE_OTHER_TABS, hwnd);
191201
return true;
@@ -213,7 +223,7 @@ bool HandleCloseButton(const MOUSEHOOKSTRUCT* pmouse) {
213223
if (!tab || !IsOnCloseButton(tab, pt)) {
214224
return false;
215225
}
216-
if (!IsNeedKeep(tab_count)) {
226+
if (!IsNeedKeep(tab_count, KeepTabTrigger::kCloseButton)) {
217227
return false;
218228
}
219229
ExecuteCommand(IDC_NEW_TAB, hwnd);
@@ -380,7 +390,7 @@ bool HandleKeepTab(WPARAM wParam) {
380390
NodePtr top_container_view = GetTopContainerView(hwnd);
381391
// Use `GetTabCount` directly since we only need tab count here (no mouse pos)
382392
int tab_count = GetTabCount(top_container_view);
383-
if (!IsNeedKeep(tab_count)) {
393+
if (!IsNeedKeep(tab_count, KeepTabTrigger::kKeyboardShortcut)) {
384394
return false;
385395
}
386396

0 commit comments

Comments
 (0)