detached 0a87b78

fix(context-menu): address remaining review follow-ups

commit
0a87b78c20a2860383aaffe85613589c5648de4a
author
brice · · 2026-04-14 12:33 UTC
parent
6cb48b9
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
7 files · +124 -103
M internal/application/usecase/build_context_menu_test.go +9 -0
@@ -26,6 +26,15 @@ func TestBuildContextMenuUseCase_Build(t *testing.T) {
2626 context: port.MenuContext{},
2727 expected: []port.MenuAction{port.MenuActionReload, port.MenuActionInspectElement},
2828 },
29+ {
30+ name: "selection context",
31+ context: port.MenuContext{HasSelection: true},
32+ expected: []port.MenuAction{
33+ port.MenuActionReload,
34+ port.MenuActionCopySelection,
35+ port.MenuActionInspectElement,
36+ },
37+ },
2938 {
3039 name: "image only",
3140 context: port.MenuContext{ImageURI: "https://example.com/image.png"},
@@ -26,6 +26,15 @@ func TestBuildContextMenuUseCase_Build(t *testing.T) {
26 context: port.MenuContext{},26 context: port.MenuContext{},
27 expected: []port.MenuAction{port.MenuActionReload, port.MenuActionInspectElement},27 expected: []port.MenuAction{port.MenuActionReload, port.MenuActionInspectElement},
28 },28 },
29+ {
30+ name: "selection context",
31+ context: port.MenuContext{HasSelection: true},
32+ expected: []port.MenuAction{
33+ port.MenuActionReload,
34+ port.MenuActionCopySelection,
35+ port.MenuActionInspectElement,
36+ },
37+ },
29 {38 {
30 name: "image only",39 name: "image only",
31 context: port.MenuContext{ImageURI: "https://example.com/image.png"},40 context: port.MenuContext{ImageURI: "https://example.com/image.png"},
M internal/infrastructure/cef/context_menu_run_context_menu_test.go +0 -94
@@ -3,105 +3,11 @@ package cef
33 import (
44 "context"
55 "testing"
6- "unsafe"
7-
8- purecef "github.com/bnema/purego-cef/cef"
96
107 "github.com/bnema/dumber/internal/application/port"
118 "github.com/stretchr/testify/require"
129 )
1310
14-type stubMenuModel struct{}
15-
16-func (stubMenuModel) IsSubMenu() bool { return false }
17-func (stubMenuModel) Clear() int32 { panic("unexpected call") }
18-func (stubMenuModel) GetCount() int { return 1 }
19-func (stubMenuModel) AddSeparator() int32 { panic("unexpected call") }
20-func (stubMenuModel) AddItem(_ int32, _ string) int32 { panic("unexpected call") }
21-func (stubMenuModel) AddCheckItem(_ int32, _ string) int32 {
22- panic("unexpected call")
23-}
24-func (stubMenuModel) AddRadioItem(_ int32, _ string, _ int32) int32 {
25- panic("unexpected call")
26-}
27-func (stubMenuModel) AddSubMenu(_ int32, _ string) purecef.MenuModel {
28- panic("unexpected call")
29-}
30-func (stubMenuModel) InsertSeparatorAt(_ int) int32 { panic("unexpected call") }
31-func (stubMenuModel) InsertItemAt(_ int, _ int32, _ string) int32 {
32- panic("unexpected call")
33-}
34-func (stubMenuModel) InsertCheckItemAt(_ int, _ int32, _ string) int32 {
35- panic("unexpected call")
36-}
37-func (stubMenuModel) InsertRadioItemAt(_ int, _ int32, _ string, _ int32) int32 {
38- panic("unexpected call")
39-}
40-func (stubMenuModel) InsertSubMenuAt(_ int, _ int32, _ string) purecef.MenuModel {
41- panic("unexpected call")
42-}
43-func (stubMenuModel) Remove(_ int32) int32 { panic("unexpected call") }
44-func (stubMenuModel) RemoveAt(_ int) int32 { panic("unexpected call") }
45-func (stubMenuModel) GetIndexOf(_ int32) int32 { panic("unexpected call") }
46-func (stubMenuModel) GetCommandIDAt(_ int) int32 { return 101 }
47-func (stubMenuModel) SetCommandIDAt(_ int, _ int32) int32 { panic("unexpected call") }
48-func (stubMenuModel) GetLabel(_ int32) string { panic("unexpected call") }
49-func (stubMenuModel) GetLabelAt(_ int) string { return "Copy" }
50-func (stubMenuModel) SetLabel(_ int32, _ string) int32 { panic("unexpected call") }
51-func (stubMenuModel) SetLabelAt(_ int, _ string) int32 { panic("unexpected call") }
52-func (stubMenuModel) GetType(_ int32) purecef.MenuItemType { panic("unexpected call") }
53-func (stubMenuModel) GetTypeAt(_ int) purecef.MenuItemType {
54- return purecef.MenuItemTypeMenuitemtypeCommand
55-}
56-func (stubMenuModel) GetGroupID(_ int32) int32 { panic("unexpected call") }
57-func (stubMenuModel) GetGroupIDAt(_ int) int32 { panic("unexpected call") }
58-func (stubMenuModel) SetGroupID(_, _ int32) int32 { panic("unexpected call") }
59-func (stubMenuModel) SetGroupIDAt(_ int, _ int32) int32 { panic("unexpected call") }
60-func (stubMenuModel) GetSubMenu(_ int32) purecef.MenuModel { panic("unexpected call") }
61-func (stubMenuModel) GetSubMenuAt(_ int) purecef.MenuModel { panic("unexpected call") }
62-func (stubMenuModel) IsVisible(_ int32) bool { panic("unexpected call") }
63-func (stubMenuModel) IsVisibleAt(_ int) bool { panic("unexpected call") }
64-func (stubMenuModel) SetVisible(_, _ int32) int32 { panic("unexpected call") }
65-func (stubMenuModel) SetVisibleAt(_ int, _ int32) int32 { panic("unexpected call") }
66-func (stubMenuModel) IsEnabled(_ int32) bool { panic("unexpected call") }
67-func (stubMenuModel) IsEnabledAt(_ int) bool { panic("unexpected call") }
68-func (stubMenuModel) SetEnabled(_, _ int32) int32 { panic("unexpected call") }
69-func (stubMenuModel) SetEnabledAt(_ int, _ int32) int32 { panic("unexpected call") }
70-func (stubMenuModel) IsChecked(_ int32) bool { panic("unexpected call") }
71-func (stubMenuModel) IsCheckedAt(_ int) bool { panic("unexpected call") }
72-func (stubMenuModel) SetChecked(_, _ int32) int32 { panic("unexpected call") }
73-func (stubMenuModel) SetCheckedAt(_ int, _ int32) int32 { panic("unexpected call") }
74-func (stubMenuModel) HasAccelerator(_ int32) bool { panic("unexpected call") }
75-func (stubMenuModel) HasAcceleratorAt(_ int) bool { panic("unexpected call") }
76-func (stubMenuModel) SetAccelerator(_, _, _, _, _ int32) int32 {
77- panic("unexpected call")
78-}
79-func (stubMenuModel) SetAcceleratorAt(_ int, _, _, _, _ int32) int32 {
80- panic("unexpected call")
81-}
82-func (stubMenuModel) RemoveAccelerator(_ int32) int32 { panic("unexpected call") }
83-func (stubMenuModel) RemoveAcceleratorAt(_ int) int32 { panic("unexpected call") }
84-func (stubMenuModel) GetAccelerator(_ int32, _, _, _, _ unsafe.Pointer) int32 {
85- panic("unexpected call")
86-}
87-func (stubMenuModel) GetAcceleratorAt(_ int, _, _, _, _ unsafe.Pointer) int32 {
88- panic("unexpected call")
89-}
90-func (stubMenuModel) SetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
91- panic("unexpected call")
92-}
93-func (stubMenuModel) SetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
94- panic("unexpected call")
95-}
96-func (stubMenuModel) GetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
97- panic("unexpected call")
98-}
99-func (stubMenuModel) GetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
100- panic("unexpected call")
101-}
102-func (stubMenuModel) SetFontList(_ int32, _ string) int32 { panic("unexpected call") }
103-func (stubMenuModel) SetFontListAt(_ int32, _ string) int32 { panic("unexpected call") }
104-
10511 type stubContextMenuBuilder struct{ items []port.MenuItem }
10612
10713 func (b stubContextMenuBuilder) Build(context.Context, port.MenuContext) []port.MenuItem {
@@ -3,105 +3,11 @@ package cef
3 import (3 import (
4 "context"4 "context"
5 "testing"5 "testing"
6- "unsafe"
7-
8- purecef "github.com/bnema/purego-cef/cef"
9 6
10 "github.com/bnema/dumber/internal/application/port"7 "github.com/bnema/dumber/internal/application/port"
11 "github.com/stretchr/testify/require"8 "github.com/stretchr/testify/require"
12 )9 )
13 10
14-type stubMenuModel struct{}
15-
16-func (stubMenuModel) IsSubMenu() bool { return false }
17-func (stubMenuModel) Clear() int32 { panic("unexpected call") }
18-func (stubMenuModel) GetCount() int { return 1 }
19-func (stubMenuModel) AddSeparator() int32 { panic("unexpected call") }
20-func (stubMenuModel) AddItem(_ int32, _ string) int32 { panic("unexpected call") }
21-func (stubMenuModel) AddCheckItem(_ int32, _ string) int32 {
22- panic("unexpected call")
23-}
24-func (stubMenuModel) AddRadioItem(_ int32, _ string, _ int32) int32 {
25- panic("unexpected call")
26-}
27-func (stubMenuModel) AddSubMenu(_ int32, _ string) purecef.MenuModel {
28- panic("unexpected call")
29-}
30-func (stubMenuModel) InsertSeparatorAt(_ int) int32 { panic("unexpected call") }
31-func (stubMenuModel) InsertItemAt(_ int, _ int32, _ string) int32 {
32- panic("unexpected call")
33-}
34-func (stubMenuModel) InsertCheckItemAt(_ int, _ int32, _ string) int32 {
35- panic("unexpected call")
36-}
37-func (stubMenuModel) InsertRadioItemAt(_ int, _ int32, _ string, _ int32) int32 {
38- panic("unexpected call")
39-}
40-func (stubMenuModel) InsertSubMenuAt(_ int, _ int32, _ string) purecef.MenuModel {
41- panic("unexpected call")
42-}
43-func (stubMenuModel) Remove(_ int32) int32 { panic("unexpected call") }
44-func (stubMenuModel) RemoveAt(_ int) int32 { panic("unexpected call") }
45-func (stubMenuModel) GetIndexOf(_ int32) int32 { panic("unexpected call") }
46-func (stubMenuModel) GetCommandIDAt(_ int) int32 { return 101 }
47-func (stubMenuModel) SetCommandIDAt(_ int, _ int32) int32 { panic("unexpected call") }
48-func (stubMenuModel) GetLabel(_ int32) string { panic("unexpected call") }
49-func (stubMenuModel) GetLabelAt(_ int) string { return "Copy" }
50-func (stubMenuModel) SetLabel(_ int32, _ string) int32 { panic("unexpected call") }
51-func (stubMenuModel) SetLabelAt(_ int, _ string) int32 { panic("unexpected call") }
52-func (stubMenuModel) GetType(_ int32) purecef.MenuItemType { panic("unexpected call") }
53-func (stubMenuModel) GetTypeAt(_ int) purecef.MenuItemType {
54- return purecef.MenuItemTypeMenuitemtypeCommand
55-}
56-func (stubMenuModel) GetGroupID(_ int32) int32 { panic("unexpected call") }
57-func (stubMenuModel) GetGroupIDAt(_ int) int32 { panic("unexpected call") }
58-func (stubMenuModel) SetGroupID(_, _ int32) int32 { panic("unexpected call") }
59-func (stubMenuModel) SetGroupIDAt(_ int, _ int32) int32 { panic("unexpected call") }
60-func (stubMenuModel) GetSubMenu(_ int32) purecef.MenuModel { panic("unexpected call") }
61-func (stubMenuModel) GetSubMenuAt(_ int) purecef.MenuModel { panic("unexpected call") }
62-func (stubMenuModel) IsVisible(_ int32) bool { panic("unexpected call") }
63-func (stubMenuModel) IsVisibleAt(_ int) bool { panic("unexpected call") }
64-func (stubMenuModel) SetVisible(_, _ int32) int32 { panic("unexpected call") }
65-func (stubMenuModel) SetVisibleAt(_ int, _ int32) int32 { panic("unexpected call") }
66-func (stubMenuModel) IsEnabled(_ int32) bool { panic("unexpected call") }
67-func (stubMenuModel) IsEnabledAt(_ int) bool { panic("unexpected call") }
68-func (stubMenuModel) SetEnabled(_, _ int32) int32 { panic("unexpected call") }
69-func (stubMenuModel) SetEnabledAt(_ int, _ int32) int32 { panic("unexpected call") }
70-func (stubMenuModel) IsChecked(_ int32) bool { panic("unexpected call") }
71-func (stubMenuModel) IsCheckedAt(_ int) bool { panic("unexpected call") }
72-func (stubMenuModel) SetChecked(_, _ int32) int32 { panic("unexpected call") }
73-func (stubMenuModel) SetCheckedAt(_ int, _ int32) int32 { panic("unexpected call") }
74-func (stubMenuModel) HasAccelerator(_ int32) bool { panic("unexpected call") }
75-func (stubMenuModel) HasAcceleratorAt(_ int) bool { panic("unexpected call") }
76-func (stubMenuModel) SetAccelerator(_, _, _, _, _ int32) int32 {
77- panic("unexpected call")
78-}
79-func (stubMenuModel) SetAcceleratorAt(_ int, _, _, _, _ int32) int32 {
80- panic("unexpected call")
81-}
82-func (stubMenuModel) RemoveAccelerator(_ int32) int32 { panic("unexpected call") }
83-func (stubMenuModel) RemoveAcceleratorAt(_ int) int32 { panic("unexpected call") }
84-func (stubMenuModel) GetAccelerator(_ int32, _, _, _, _ unsafe.Pointer) int32 {
85- panic("unexpected call")
86-}
87-func (stubMenuModel) GetAcceleratorAt(_ int, _, _, _, _ unsafe.Pointer) int32 {
88- panic("unexpected call")
89-}
90-func (stubMenuModel) SetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
91- panic("unexpected call")
92-}
93-func (stubMenuModel) SetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
94- panic("unexpected call")
95-}
96-func (stubMenuModel) GetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
97- panic("unexpected call")
98-}
99-func (stubMenuModel) GetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
100- panic("unexpected call")
101-}
102-func (stubMenuModel) SetFontList(_ int32, _ string) int32 { panic("unexpected call") }
103-func (stubMenuModel) SetFontListAt(_ int32, _ string) int32 { panic("unexpected call") }
104-
105 type stubContextMenuBuilder struct{ items []port.MenuItem }11 type stubContextMenuBuilder struct{ items []port.MenuItem }
106 12
107 func (b stubContextMenuBuilder) Build(context.Context, port.MenuContext) []port.MenuItem {13 func (b stubContextMenuBuilder) Build(context.Context, port.MenuContext) []port.MenuItem {
A internal/infrastructure/cef/testutil_test.go +98 -0
@@ -0,0 +1,98 @@
1+package cef
2+
3+import (
4+ "unsafe"
5+
6+ purecef "github.com/bnema/purego-cef/cef"
7+)
8+
9+type stubMenuModel struct{}
10+
11+func (stubMenuModel) IsSubMenu() bool { return false }
12+func (stubMenuModel) Clear() int32 { panic("unexpected call") }
13+func (stubMenuModel) GetCount() int { return 1 }
14+func (stubMenuModel) AddSeparator() int32 { panic("unexpected call") }
15+func (stubMenuModel) AddItem(_ int32, _ string) int32 { panic("unexpected call") }
16+func (stubMenuModel) AddCheckItem(_ int32, _ string) int32 {
17+ panic("unexpected call")
18+}
19+func (stubMenuModel) AddRadioItem(_ int32, _ string, _ int32) int32 {
20+ panic("unexpected call")
21+}
22+func (stubMenuModel) AddSubMenu(_ int32, _ string) purecef.MenuModel {
23+ panic("unexpected call")
24+}
25+func (stubMenuModel) InsertSeparatorAt(_ int) int32 { panic("unexpected call") }
26+func (stubMenuModel) InsertItemAt(_ int, _ int32, _ string) int32 {
27+ panic("unexpected call")
28+}
29+func (stubMenuModel) InsertCheckItemAt(_ int, _ int32, _ string) int32 {
30+ panic("unexpected call")
31+}
32+func (stubMenuModel) InsertRadioItemAt(_ int, _ int32, _ string, _ int32) int32 {
33+ panic("unexpected call")
34+}
35+func (stubMenuModel) InsertSubMenuAt(_ int, _ int32, _ string) purecef.MenuModel {
36+ panic("unexpected call")
37+}
38+func (stubMenuModel) Remove(_ int32) int32 { panic("unexpected call") }
39+func (stubMenuModel) RemoveAt(_ int) int32 { panic("unexpected call") }
40+func (stubMenuModel) GetIndexOf(_ int32) int32 { panic("unexpected call") }
41+func (stubMenuModel) GetCommandIDAt(_ int) int32 { return 101 }
42+func (stubMenuModel) SetCommandIDAt(_ int, _ int32) int32 { panic("unexpected call") }
43+func (stubMenuModel) GetLabel(_ int32) string { panic("unexpected call") }
44+func (stubMenuModel) GetLabelAt(_ int) string { return "Copy" }
45+func (stubMenuModel) SetLabel(_ int32, _ string) int32 { panic("unexpected call") }
46+func (stubMenuModel) SetLabelAt(_ int, _ string) int32 { panic("unexpected call") }
47+func (stubMenuModel) GetType(_ int32) purecef.MenuItemType { panic("unexpected call") }
48+func (stubMenuModel) GetTypeAt(_ int) purecef.MenuItemType {
49+ return purecef.MenuItemTypeMenuitemtypeCommand
50+}
51+func (stubMenuModel) GetGroupID(_ int32) int32 { panic("unexpected call") }
52+func (stubMenuModel) GetGroupIDAt(_ int) int32 { panic("unexpected call") }
53+func (stubMenuModel) SetGroupID(_, _ int32) int32 { panic("unexpected call") }
54+func (stubMenuModel) SetGroupIDAt(_ int, _ int32) int32 { panic("unexpected call") }
55+func (stubMenuModel) GetSubMenu(_ int32) purecef.MenuModel { panic("unexpected call") }
56+func (stubMenuModel) GetSubMenuAt(_ int) purecef.MenuModel { panic("unexpected call") }
57+func (stubMenuModel) IsVisible(_ int32) bool { panic("unexpected call") }
58+func (stubMenuModel) IsVisibleAt(_ int) bool { panic("unexpected call") }
59+func (stubMenuModel) SetVisible(_, _ int32) int32 { panic("unexpected call") }
60+func (stubMenuModel) SetVisibleAt(_ int, _ int32) int32 { panic("unexpected call") }
61+func (stubMenuModel) IsEnabled(_ int32) bool { panic("unexpected call") }
62+func (stubMenuModel) IsEnabledAt(_ int) bool { panic("unexpected call") }
63+func (stubMenuModel) SetEnabled(_, _ int32) int32 { panic("unexpected call") }
64+func (stubMenuModel) SetEnabledAt(_ int, _ int32) int32 { panic("unexpected call") }
65+func (stubMenuModel) IsChecked(_ int32) bool { panic("unexpected call") }
66+func (stubMenuModel) IsCheckedAt(_ int) bool { panic("unexpected call") }
67+func (stubMenuModel) SetChecked(_, _ int32) int32 { panic("unexpected call") }
68+func (stubMenuModel) SetCheckedAt(_ int, _ int32) int32 { panic("unexpected call") }
69+func (stubMenuModel) HasAccelerator(_ int32) bool { panic("unexpected call") }
70+func (stubMenuModel) HasAcceleratorAt(_ int) bool { panic("unexpected call") }
71+func (stubMenuModel) SetAccelerator(_, _, _, _, _ int32) int32 {
72+ panic("unexpected call")
73+}
74+func (stubMenuModel) SetAcceleratorAt(_ int, _, _, _, _ int32) int32 {
75+ panic("unexpected call")
76+}
77+func (stubMenuModel) RemoveAccelerator(_ int32) int32 { panic("unexpected call") }
78+func (stubMenuModel) RemoveAcceleratorAt(_ int) int32 { panic("unexpected call") }
79+func (stubMenuModel) GetAccelerator(_ int32, _, _, _, _ unsafe.Pointer) int32 {
80+ panic("unexpected call")
81+}
82+func (stubMenuModel) GetAcceleratorAt(_ int, _, _, _, _ unsafe.Pointer) int32 {
83+ panic("unexpected call")
84+}
85+func (stubMenuModel) SetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
86+ panic("unexpected call")
87+}
88+func (stubMenuModel) SetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
89+ panic("unexpected call")
90+}
91+func (stubMenuModel) GetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
92+ panic("unexpected call")
93+}
94+func (stubMenuModel) GetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
95+ panic("unexpected call")
96+}
97+func (stubMenuModel) SetFontList(_ int32, _ string) int32 { panic("unexpected call") }
98+func (stubMenuModel) SetFontListAt(_ int32, _ string) int32 { panic("unexpected call") }
@@ -0,0 +1,98 @@
1+package cef
2+
3+import (
4+ "unsafe"
5+
6+ purecef "github.com/bnema/purego-cef/cef"
7+)
8+
9+type stubMenuModel struct{}
10+
11+func (stubMenuModel) IsSubMenu() bool { return false }
12+func (stubMenuModel) Clear() int32 { panic("unexpected call") }
13+func (stubMenuModel) GetCount() int { return 1 }
14+func (stubMenuModel) AddSeparator() int32 { panic("unexpected call") }
15+func (stubMenuModel) AddItem(_ int32, _ string) int32 { panic("unexpected call") }
16+func (stubMenuModel) AddCheckItem(_ int32, _ string) int32 {
17+ panic("unexpected call")
18+}
19+func (stubMenuModel) AddRadioItem(_ int32, _ string, _ int32) int32 {
20+ panic("unexpected call")
21+}
22+func (stubMenuModel) AddSubMenu(_ int32, _ string) purecef.MenuModel {
23+ panic("unexpected call")
24+}
25+func (stubMenuModel) InsertSeparatorAt(_ int) int32 { panic("unexpected call") }
26+func (stubMenuModel) InsertItemAt(_ int, _ int32, _ string) int32 {
27+ panic("unexpected call")
28+}
29+func (stubMenuModel) InsertCheckItemAt(_ int, _ int32, _ string) int32 {
30+ panic("unexpected call")
31+}
32+func (stubMenuModel) InsertRadioItemAt(_ int, _ int32, _ string, _ int32) int32 {
33+ panic("unexpected call")
34+}
35+func (stubMenuModel) InsertSubMenuAt(_ int, _ int32, _ string) purecef.MenuModel {
36+ panic("unexpected call")
37+}
38+func (stubMenuModel) Remove(_ int32) int32 { panic("unexpected call") }
39+func (stubMenuModel) RemoveAt(_ int) int32 { panic("unexpected call") }
40+func (stubMenuModel) GetIndexOf(_ int32) int32 { panic("unexpected call") }
41+func (stubMenuModel) GetCommandIDAt(_ int) int32 { return 101 }
42+func (stubMenuModel) SetCommandIDAt(_ int, _ int32) int32 { panic("unexpected call") }
43+func (stubMenuModel) GetLabel(_ int32) string { panic("unexpected call") }
44+func (stubMenuModel) GetLabelAt(_ int) string { return "Copy" }
45+func (stubMenuModel) SetLabel(_ int32, _ string) int32 { panic("unexpected call") }
46+func (stubMenuModel) SetLabelAt(_ int, _ string) int32 { panic("unexpected call") }
47+func (stubMenuModel) GetType(_ int32) purecef.MenuItemType { panic("unexpected call") }
48+func (stubMenuModel) GetTypeAt(_ int) purecef.MenuItemType {
49+ return purecef.MenuItemTypeMenuitemtypeCommand
50+}
51+func (stubMenuModel) GetGroupID(_ int32) int32 { panic("unexpected call") }
52+func (stubMenuModel) GetGroupIDAt(_ int) int32 { panic("unexpected call") }
53+func (stubMenuModel) SetGroupID(_, _ int32) int32 { panic("unexpected call") }
54+func (stubMenuModel) SetGroupIDAt(_ int, _ int32) int32 { panic("unexpected call") }
55+func (stubMenuModel) GetSubMenu(_ int32) purecef.MenuModel { panic("unexpected call") }
56+func (stubMenuModel) GetSubMenuAt(_ int) purecef.MenuModel { panic("unexpected call") }
57+func (stubMenuModel) IsVisible(_ int32) bool { panic("unexpected call") }
58+func (stubMenuModel) IsVisibleAt(_ int) bool { panic("unexpected call") }
59+func (stubMenuModel) SetVisible(_, _ int32) int32 { panic("unexpected call") }
60+func (stubMenuModel) SetVisibleAt(_ int, _ int32) int32 { panic("unexpected call") }
61+func (stubMenuModel) IsEnabled(_ int32) bool { panic("unexpected call") }
62+func (stubMenuModel) IsEnabledAt(_ int) bool { panic("unexpected call") }
63+func (stubMenuModel) SetEnabled(_, _ int32) int32 { panic("unexpected call") }
64+func (stubMenuModel) SetEnabledAt(_ int, _ int32) int32 { panic("unexpected call") }
65+func (stubMenuModel) IsChecked(_ int32) bool { panic("unexpected call") }
66+func (stubMenuModel) IsCheckedAt(_ int) bool { panic("unexpected call") }
67+func (stubMenuModel) SetChecked(_, _ int32) int32 { panic("unexpected call") }
68+func (stubMenuModel) SetCheckedAt(_ int, _ int32) int32 { panic("unexpected call") }
69+func (stubMenuModel) HasAccelerator(_ int32) bool { panic("unexpected call") }
70+func (stubMenuModel) HasAcceleratorAt(_ int) bool { panic("unexpected call") }
71+func (stubMenuModel) SetAccelerator(_, _, _, _, _ int32) int32 {
72+ panic("unexpected call")
73+}
74+func (stubMenuModel) SetAcceleratorAt(_ int, _, _, _, _ int32) int32 {
75+ panic("unexpected call")
76+}
77+func (stubMenuModel) RemoveAccelerator(_ int32) int32 { panic("unexpected call") }
78+func (stubMenuModel) RemoveAcceleratorAt(_ int) int32 { panic("unexpected call") }
79+func (stubMenuModel) GetAccelerator(_ int32, _, _, _, _ unsafe.Pointer) int32 {
80+ panic("unexpected call")
81+}
82+func (stubMenuModel) GetAcceleratorAt(_ int, _, _, _, _ unsafe.Pointer) int32 {
83+ panic("unexpected call")
84+}
85+func (stubMenuModel) SetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
86+ panic("unexpected call")
87+}
88+func (stubMenuModel) SetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
89+ panic("unexpected call")
90+}
91+func (stubMenuModel) GetColor(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
92+ panic("unexpected call")
93+}
94+func (stubMenuModel) GetColorAt(_ int32, _ purecef.MenuColorType, _ uintptr) int32 {
95+ panic("unexpected call")
96+}
97+func (stubMenuModel) SetFontList(_ int32, _ string) int32 { panic("unexpected call") }
98+func (stubMenuModel) SetFontListAt(_ int32, _ string) int32 { panic("unexpected call") }
M internal/infrastructure/config/loader.go +4 -4
@@ -136,15 +136,15 @@ func (m *Manager) readConfigFile() error {
136136 }
137137 }
138138
139- // Transform legacy action bindings before unmarshaling
140- m.transformLegacyActionBindings()
139+ // Transform legacy action bindings and engine config before unmarshaling.
140+ m.transformLegacyConfig()
141141
142142 return nil
143143 }
144144
145-// transformLegacyActionBindings converts old-format action bindings to new format.
145+// transformLegacyConfig converts old-format action bindings and engine config to the new format.
146146 // This is called after reading config but before unmarshaling.
147-func (m *Manager) transformLegacyActionBindings() {
147+func (m *Manager) transformLegacyConfig() {
148148 rawConfig := m.viper.AllSettings()
149149 transformer := NewLegacyConfigTransformer()
150150 transformer.TransformLegacyActions(rawConfig)
@@ -136,15 +136,15 @@ func (m *Manager) readConfigFile() error {
136 }136 }
137 }137 }
138 138
139- // Transform legacy action bindings before unmarshaling139+ // Transform legacy action bindings and engine config before unmarshaling.
140- m.transformLegacyActionBindings()140+ m.transformLegacyConfig()
141 141
142 return nil142 return nil
143 }143 }
144 144
145-// transformLegacyActionBindings converts old-format action bindings to new format.145+// transformLegacyConfig converts old-format action bindings and engine config to the new format.
146 // This is called after reading config but before unmarshaling.146 // This is called after reading config but before unmarshaling.
147-func (m *Manager) transformLegacyActionBindings() {147+func (m *Manager) transformLegacyConfig() {
148 rawConfig := m.viper.AllSettings()148 rawConfig := m.viper.AllSettings()
149 transformer := NewLegacyConfigTransformer()149 transformer := NewLegacyConfigTransformer()
150 transformer.TransformLegacyActions(rawConfig)150 transformer.TransformLegacyActions(rawConfig)
M internal/infrastructure/gtkmenu/renderer.go +5 -0
@@ -3,7 +3,9 @@ package gtkmenu
33 import (
44 "github.com/bnema/dumber/internal/application/port"
55 "github.com/bnema/puregotk/v4/gdk"
6+ "github.com/bnema/puregotk/v4/gobject"
67 "github.com/bnema/puregotk/v4/gtk"
8+ "unsafe"
79 )
810
911 type renderItem struct {
@@ -198,6 +200,9 @@ func overlayFromWidget(widget *gtk.Widget) *gtk.Overlay {
198200 if widget == nil || widget.GoPointer() == 0 {
199201 return nil
200202 }
203+ if !gobject.TypeCheckInstanceIsA((*gobject.TypeInstance)(unsafe.Pointer(widget.GoPointer())), gtk.OverlayGLibType()) {
204+ return nil
205+ }
201206 return gtk.OverlayNewFromInternalPtr(widget.GoPointer())
202207 }
203208
@@ -3,7 +3,9 @@ package gtkmenu
3 import (3 import (
4 "github.com/bnema/dumber/internal/application/port"4 "github.com/bnema/dumber/internal/application/port"
5 "github.com/bnema/puregotk/v4/gdk"5 "github.com/bnema/puregotk/v4/gdk"
6+ "github.com/bnema/puregotk/v4/gobject"
6 "github.com/bnema/puregotk/v4/gtk"7 "github.com/bnema/puregotk/v4/gtk"
8+ "unsafe"
7 )9 )
8 10
9 type renderItem struct {11 type renderItem struct {
@@ -198,6 +200,9 @@ func overlayFromWidget(widget *gtk.Widget) *gtk.Overlay {
198 if widget == nil || widget.GoPointer() == 0 {200 if widget == nil || widget.GoPointer() == 0 {
199 return nil201 return nil
200 }202 }
203+ if !gobject.TypeCheckInstanceIsA((*gobject.TypeInstance)(unsafe.Pointer(widget.GoPointer())), gtk.OverlayGLibType()) {
204+ return nil
205+ }
201 return gtk.OverlayNewFromInternalPtr(widget.GoPointer())206 return gtk.OverlayNewFromInternalPtr(widget.GoPointer())
202 }207 }
203 208
M internal/infrastructure/webkit/context_menu.go +8 -4
@@ -1,8 +1,10 @@
11 package webkit
22
33 import (
4+ "bytes"
45 "context"
56 "encoding/base64"
7+ "errors"
68 "fmt"
79 "io"
810 "mime"
@@ -71,16 +73,18 @@ func (r *contextMenuResolver) ResolveImageData(ctx context.Context, imageURI str
7173 return entity.ImageData{}, fmt.Errorf("fetch image: HTTP %d", resp.StatusCode)
7274 }
7375
74- data, err := io.ReadAll(io.LimitReader(resp.Body, maxImageFetchBytes+1))
75- if err != nil {
76+ var buf bytes.Buffer
77+ n, err := io.CopyN(&buf, resp.Body, maxImageFetchBytes+1)
78+ if err != nil && !errors.Is(err, io.EOF) && !errors.Is(err, io.ErrUnexpectedEOF) {
7679 return entity.ImageData{}, fmt.Errorf("read image body: %w", err)
7780 }
78- if len(data) == 0 {
81+ if n == 0 {
7982 return entity.ImageData{}, fmt.Errorf("read image body: empty image data")
8083 }
81- if len(data) > maxImageFetchBytes {
84+ if n > maxImageFetchBytes {
8285 return entity.ImageData{}, fmt.Errorf("read image body: image too large (limit %d bytes)", maxImageFetchBytes)
8386 }
87+ data := buf.Bytes()
8488 responseURL := parsed.String()
8589 if resp.Request != nil && resp.Request.URL != nil {
8690 responseURL = resp.Request.URL.String()
@@ -1,8 +1,10 @@
1 package webkit1 package webkit
2 2
3 import (3 import (
4+ "bytes"
4 "context"5 "context"
5 "encoding/base64"6 "encoding/base64"
7+ "errors"
6 "fmt"8 "fmt"
7 "io"9 "io"
8 "mime"10 "mime"
@@ -71,16 +73,18 @@ func (r *contextMenuResolver) ResolveImageData(ctx context.Context, imageURI str
71 return entity.ImageData{}, fmt.Errorf("fetch image: HTTP %d", resp.StatusCode)73 return entity.ImageData{}, fmt.Errorf("fetch image: HTTP %d", resp.StatusCode)
72 }74 }
73 75
74- data, err := io.ReadAll(io.LimitReader(resp.Body, maxImageFetchBytes+1))76+ var buf bytes.Buffer
75- if err != nil {77+ n, err := io.CopyN(&buf, resp.Body, maxImageFetchBytes+1)
78+ if err != nil && !errors.Is(err, io.EOF) && !errors.Is(err, io.ErrUnexpectedEOF) {
76 return entity.ImageData{}, fmt.Errorf("read image body: %w", err)79 return entity.ImageData{}, fmt.Errorf("read image body: %w", err)
77 }80 }
78- if len(data) == 0 {81+ if n == 0 {
79 return entity.ImageData{}, fmt.Errorf("read image body: empty image data")82 return entity.ImageData{}, fmt.Errorf("read image body: empty image data")
80 }83 }
81- if len(data) > maxImageFetchBytes {84+ if n > maxImageFetchBytes {
82 return entity.ImageData{}, fmt.Errorf("read image body: image too large (limit %d bytes)", maxImageFetchBytes)85 return entity.ImageData{}, fmt.Errorf("read image body: image too large (limit %d bytes)", maxImageFetchBytes)
83 }86 }
87+ data := buf.Bytes()
84 responseURL := parsed.String()88 responseURL := parsed.String()
85 if resp.Request != nil && resp.Request.URL != nil {89 if resp.Request != nil && resp.Request.URL != nil {
86 responseURL = resp.Request.URL.String()90 responseURL = resp.Request.URL.String()
M internal/infrastructure/webkit/context_menu_test.go +0 -1
@@ -235,7 +235,6 @@ func TestResolveImageData(t *testing.T) {
235235 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
236236 w.Header().Set("Content-Type", "image/png")
237237 w.Write([]byte("<html><body>not really an image</body></html>"))
238- _ = r
239238 }))
240239 defer srv.Close()
241240
@@ -235,7 +235,6 @@ func TestResolveImageData(t *testing.T) {
235 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {235 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
236 w.Header().Set("Content-Type", "image/png")236 w.Header().Set("Content-Type", "image/png")
237 w.Write([]byte("<html><body>not really an image</body></html>"))237 w.Write([]byte("<html><body>not really an image</body></html>"))
238- _ = r
239 }))238 }))
240 defer srv.Close()239 defer srv.Close()
241 240

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close