detached 7929813

fix: harden omnibox ghost accept and address remaining review issues

commit
792981397b7feeac99c6f7e34c975515b82e3e81
author
brice · · 2026-02-07 06:55 UTC
committer
brice · · 2026-02-07 07:04 UTC
parent
b764bd2
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
12 files · +237 -53
M internal/application/port/mocks/mocks.go +159 -0
@@ -1281,6 +1281,165 @@ func (_c *MockDatabaseProvider_IsInitialized_Call) RunAndReturn(run func() bool)
12811281 return _c
12821282 }
12831283
1284+// NewMockDownloadResponse creates a new instance of MockDownloadResponse. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
1285+// The first argument is typically a *testing.T value.
1286+func NewMockDownloadResponse(t interface {
1287+ mock.TestingT
1288+ Cleanup(func())
1289+}) *MockDownloadResponse {
1290+ mock := &MockDownloadResponse{}
1291+ mock.Mock.Test(t)
1292+
1293+ t.Cleanup(func() { mock.AssertExpectations(t) })
1294+
1295+ return mock
1296+}
1297+
1298+// MockDownloadResponse is an autogenerated mock type for the DownloadResponse type
1299+type MockDownloadResponse struct {
1300+ mock.Mock
1301+}
1302+
1303+type MockDownloadResponse_Expecter struct {
1304+ mock *mock.Mock
1305+}
1306+
1307+func (_m *MockDownloadResponse) EXPECT() *MockDownloadResponse_Expecter {
1308+ return &MockDownloadResponse_Expecter{mock: &_m.Mock}
1309+}
1310+
1311+// GetMimeType provides a mock function for the type MockDownloadResponse
1312+func (_mock *MockDownloadResponse) GetMimeType() string {
1313+ ret := _mock.Called()
1314+
1315+ if len(ret) == 0 {
1316+ panic("no return value specified for GetMimeType")
1317+ }
1318+
1319+ var r0 string
1320+ if returnFunc, ok := ret.Get(0).(func() string); ok {
1321+ r0 = returnFunc()
1322+ } else {
1323+ r0 = ret.Get(0).(string)
1324+ }
1325+ return r0
1326+}
1327+
1328+// MockDownloadResponse_GetMimeType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetMimeType'
1329+type MockDownloadResponse_GetMimeType_Call struct {
1330+ *mock.Call
1331+}
1332+
1333+// GetMimeType is a helper method to define mock.On call
1334+func (_e *MockDownloadResponse_Expecter) GetMimeType() *MockDownloadResponse_GetMimeType_Call {
1335+ return &MockDownloadResponse_GetMimeType_Call{Call: _e.mock.On("GetMimeType")}
1336+}
1337+
1338+func (_c *MockDownloadResponse_GetMimeType_Call) Run(run func()) *MockDownloadResponse_GetMimeType_Call {
1339+ _c.Call.Run(func(args mock.Arguments) {
1340+ run()
1341+ })
1342+ return _c
1343+}
1344+
1345+func (_c *MockDownloadResponse_GetMimeType_Call) Return(s string) *MockDownloadResponse_GetMimeType_Call {
1346+ _c.Call.Return(s)
1347+ return _c
1348+}
1349+
1350+func (_c *MockDownloadResponse_GetMimeType_Call) RunAndReturn(run func() string) *MockDownloadResponse_GetMimeType_Call {
1351+ _c.Call.Return(run)
1352+ return _c
1353+}
1354+
1355+// GetSuggestedFilename provides a mock function for the type MockDownloadResponse
1356+func (_mock *MockDownloadResponse) GetSuggestedFilename() string {
1357+ ret := _mock.Called()
1358+
1359+ if len(ret) == 0 {
1360+ panic("no return value specified for GetSuggestedFilename")
1361+ }
1362+
1363+ var r0 string
1364+ if returnFunc, ok := ret.Get(0).(func() string); ok {
1365+ r0 = returnFunc()
1366+ } else {
1367+ r0 = ret.Get(0).(string)
1368+ }
1369+ return r0
1370+}
1371+
1372+// MockDownloadResponse_GetSuggestedFilename_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSuggestedFilename'
1373+type MockDownloadResponse_GetSuggestedFilename_Call struct {
1374+ *mock.Call
1375+}
1376+
1377+// GetSuggestedFilename is a helper method to define mock.On call
1378+func (_e *MockDownloadResponse_Expecter) GetSuggestedFilename() *MockDownloadResponse_GetSuggestedFilename_Call {
1379+ return &MockDownloadResponse_GetSuggestedFilename_Call{Call: _e.mock.On("GetSuggestedFilename")}
1380+}
1381+
1382+func (_c *MockDownloadResponse_GetSuggestedFilename_Call) Run(run func()) *MockDownloadResponse_GetSuggestedFilename_Call {
1383+ _c.Call.Run(func(args mock.Arguments) {
1384+ run()
1385+ })
1386+ return _c
1387+}
1388+
1389+func (_c *MockDownloadResponse_GetSuggestedFilename_Call) Return(s string) *MockDownloadResponse_GetSuggestedFilename_Call {
1390+ _c.Call.Return(s)
1391+ return _c
1392+}
1393+
1394+func (_c *MockDownloadResponse_GetSuggestedFilename_Call) RunAndReturn(run func() string) *MockDownloadResponse_GetSuggestedFilename_Call {
1395+ _c.Call.Return(run)
1396+ return _c
1397+}
1398+
1399+// GetUri provides a mock function for the type MockDownloadResponse
1400+func (_mock *MockDownloadResponse) GetUri() string {
1401+ ret := _mock.Called()
1402+
1403+ if len(ret) == 0 {
1404+ panic("no return value specified for GetUri")
1405+ }
1406+
1407+ var r0 string
1408+ if returnFunc, ok := ret.Get(0).(func() string); ok {
1409+ r0 = returnFunc()
1410+ } else {
1411+ r0 = ret.Get(0).(string)
1412+ }
1413+ return r0
1414+}
1415+
1416+// MockDownloadResponse_GetUri_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUri'
1417+type MockDownloadResponse_GetUri_Call struct {
1418+ *mock.Call
1419+}
1420+
1421+// GetUri is a helper method to define mock.On call
1422+func (_e *MockDownloadResponse_Expecter) GetUri() *MockDownloadResponse_GetUri_Call {
1423+ return &MockDownloadResponse_GetUri_Call{Call: _e.mock.On("GetUri")}
1424+}
1425+
1426+func (_c *MockDownloadResponse_GetUri_Call) Run(run func()) *MockDownloadResponse_GetUri_Call {
1427+ _c.Call.Run(func(args mock.Arguments) {
1428+ run()
1429+ })
1430+ return _c
1431+}
1432+
1433+func (_c *MockDownloadResponse_GetUri_Call) Return(s string) *MockDownloadResponse_GetUri_Call {
1434+ _c.Call.Return(s)
1435+ return _c
1436+}
1437+
1438+func (_c *MockDownloadResponse_GetUri_Call) RunAndReturn(run func() string) *MockDownloadResponse_GetUri_Call {
1439+ _c.Call.Return(run)
1440+ return _c
1441+}
1442+
12841443 // NewMockFontDetector creates a new instance of MockFontDetector. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
12851444 // The first argument is typically a *testing.T value.
12861445 func NewMockFontDetector(t interface {
@@ -1281,6 +1281,165 @@ func (_c *MockDatabaseProvider_IsInitialized_Call) RunAndReturn(run func() bool)
1281 return _c1281 return _c
1282 }1282 }
1283 1283
1284+// NewMockDownloadResponse creates a new instance of MockDownloadResponse. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
1285+// The first argument is typically a *testing.T value.
1286+func NewMockDownloadResponse(t interface {
1287+ mock.TestingT
1288+ Cleanup(func())
1289+}) *MockDownloadResponse {
1290+ mock := &MockDownloadResponse{}
1291+ mock.Mock.Test(t)
1292+
1293+ t.Cleanup(func() { mock.AssertExpectations(t) })
1294+
1295+ return mock
1296+}
1297+
1298+// MockDownloadResponse is an autogenerated mock type for the DownloadResponse type
1299+type MockDownloadResponse struct {
1300+ mock.Mock
1301+}
1302+
1303+type MockDownloadResponse_Expecter struct {
1304+ mock *mock.Mock
1305+}
1306+
1307+func (_m *MockDownloadResponse) EXPECT() *MockDownloadResponse_Expecter {
1308+ return &MockDownloadResponse_Expecter{mock: &_m.Mock}
1309+}
1310+
1311+// GetMimeType provides a mock function for the type MockDownloadResponse
1312+func (_mock *MockDownloadResponse) GetMimeType() string {
1313+ ret := _mock.Called()
1314+
1315+ if len(ret) == 0 {
1316+ panic("no return value specified for GetMimeType")
1317+ }
1318+
1319+ var r0 string
1320+ if returnFunc, ok := ret.Get(0).(func() string); ok {
1321+ r0 = returnFunc()
1322+ } else {
1323+ r0 = ret.Get(0).(string)
1324+ }
1325+ return r0
1326+}
1327+
1328+// MockDownloadResponse_GetMimeType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetMimeType'
1329+type MockDownloadResponse_GetMimeType_Call struct {
1330+ *mock.Call
1331+}
1332+
1333+// GetMimeType is a helper method to define mock.On call
1334+func (_e *MockDownloadResponse_Expecter) GetMimeType() *MockDownloadResponse_GetMimeType_Call {
1335+ return &MockDownloadResponse_GetMimeType_Call{Call: _e.mock.On("GetMimeType")}
1336+}
1337+
1338+func (_c *MockDownloadResponse_GetMimeType_Call) Run(run func()) *MockDownloadResponse_GetMimeType_Call {
1339+ _c.Call.Run(func(args mock.Arguments) {
1340+ run()
1341+ })
1342+ return _c
1343+}
1344+
1345+func (_c *MockDownloadResponse_GetMimeType_Call) Return(s string) *MockDownloadResponse_GetMimeType_Call {
1346+ _c.Call.Return(s)
1347+ return _c
1348+}
1349+
1350+func (_c *MockDownloadResponse_GetMimeType_Call) RunAndReturn(run func() string) *MockDownloadResponse_GetMimeType_Call {
1351+ _c.Call.Return(run)
1352+ return _c
1353+}
1354+
1355+// GetSuggestedFilename provides a mock function for the type MockDownloadResponse
1356+func (_mock *MockDownloadResponse) GetSuggestedFilename() string {
1357+ ret := _mock.Called()
1358+
1359+ if len(ret) == 0 {
1360+ panic("no return value specified for GetSuggestedFilename")
1361+ }
1362+
1363+ var r0 string
1364+ if returnFunc, ok := ret.Get(0).(func() string); ok {
1365+ r0 = returnFunc()
1366+ } else {
1367+ r0 = ret.Get(0).(string)
1368+ }
1369+ return r0
1370+}
1371+
1372+// MockDownloadResponse_GetSuggestedFilename_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSuggestedFilename'
1373+type MockDownloadResponse_GetSuggestedFilename_Call struct {
1374+ *mock.Call
1375+}
1376+
1377+// GetSuggestedFilename is a helper method to define mock.On call
1378+func (_e *MockDownloadResponse_Expecter) GetSuggestedFilename() *MockDownloadResponse_GetSuggestedFilename_Call {
1379+ return &MockDownloadResponse_GetSuggestedFilename_Call{Call: _e.mock.On("GetSuggestedFilename")}
1380+}
1381+
1382+func (_c *MockDownloadResponse_GetSuggestedFilename_Call) Run(run func()) *MockDownloadResponse_GetSuggestedFilename_Call {
1383+ _c.Call.Run(func(args mock.Arguments) {
1384+ run()
1385+ })
1386+ return _c
1387+}
1388+
1389+func (_c *MockDownloadResponse_GetSuggestedFilename_Call) Return(s string) *MockDownloadResponse_GetSuggestedFilename_Call {
1390+ _c.Call.Return(s)
1391+ return _c
1392+}
1393+
1394+func (_c *MockDownloadResponse_GetSuggestedFilename_Call) RunAndReturn(run func() string) *MockDownloadResponse_GetSuggestedFilename_Call {
1395+ _c.Call.Return(run)
1396+ return _c
1397+}
1398+
1399+// GetUri provides a mock function for the type MockDownloadResponse
1400+func (_mock *MockDownloadResponse) GetUri() string {
1401+ ret := _mock.Called()
1402+
1403+ if len(ret) == 0 {
1404+ panic("no return value specified for GetUri")
1405+ }
1406+
1407+ var r0 string
1408+ if returnFunc, ok := ret.Get(0).(func() string); ok {
1409+ r0 = returnFunc()
1410+ } else {
1411+ r0 = ret.Get(0).(string)
1412+ }
1413+ return r0
1414+}
1415+
1416+// MockDownloadResponse_GetUri_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUri'
1417+type MockDownloadResponse_GetUri_Call struct {
1418+ *mock.Call
1419+}
1420+
1421+// GetUri is a helper method to define mock.On call
1422+func (_e *MockDownloadResponse_Expecter) GetUri() *MockDownloadResponse_GetUri_Call {
1423+ return &MockDownloadResponse_GetUri_Call{Call: _e.mock.On("GetUri")}
1424+}
1425+
1426+func (_c *MockDownloadResponse_GetUri_Call) Run(run func()) *MockDownloadResponse_GetUri_Call {
1427+ _c.Call.Run(func(args mock.Arguments) {
1428+ run()
1429+ })
1430+ return _c
1431+}
1432+
1433+func (_c *MockDownloadResponse_GetUri_Call) Return(s string) *MockDownloadResponse_GetUri_Call {
1434+ _c.Call.Return(s)
1435+ return _c
1436+}
1437+
1438+func (_c *MockDownloadResponse_GetUri_Call) RunAndReturn(run func() string) *MockDownloadResponse_GetUri_Call {
1439+ _c.Call.Return(run)
1440+ return _c
1441+}
1442+
1284 // NewMockFontDetector creates a new instance of MockFontDetector. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.1443 // NewMockFontDetector creates a new instance of MockFontDetector. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
1285 // The first argument is typically a *testing.T value.1444 // The first argument is typically a *testing.T value.
1286 func NewMockFontDetector(t interface {1445 func NewMockFontDetector(t interface {
M internal/application/usecase/navigate.go +4 -0
@@ -294,6 +294,10 @@ func (uc *NavigateUseCase) UpdateHistoryTitle(ctx context.Context, historyURL, t
294294 historyURL = canonicalizeURLForHistory(historyURL, historyCanonicalizationOptions{
295295 StripTrackingParams: stripTrackingParamsForHistoryDedup,
296296 })
297+ if historyURL == "" {
298+ log.Debug().Str("title", title).Msg("history URL empty after canonicalization, skipping title update")
299+ return nil
300+ }
297301 log.Debug().Str("url", logging.TruncateURL(historyURL, logURLMaxLen)).Str("title", title).Msg("updating history title")
298302
299303 entry, err := uc.historyRepo.FindByURL(ctx, historyURL)
@@ -294,6 +294,10 @@ func (uc *NavigateUseCase) UpdateHistoryTitle(ctx context.Context, historyURL, t
294 historyURL = canonicalizeURLForHistory(historyURL, historyCanonicalizationOptions{294 historyURL = canonicalizeURLForHistory(historyURL, historyCanonicalizationOptions{
295 StripTrackingParams: stripTrackingParamsForHistoryDedup,295 StripTrackingParams: stripTrackingParamsForHistoryDedup,
296 })296 })
297+ if historyURL == "" {
298+ log.Debug().Str("title", title).Msg("history URL empty after canonicalization, skipping title update")
299+ return nil
300+ }
297 log.Debug().Str("url", logging.TruncateURL(historyURL, logURLMaxLen)).Str("title", title).Msg("updating history title")301 log.Debug().Str("url", logging.TruncateURL(historyURL, logURLMaxLen)).Str("title", title).Msg("updating history title")
298 302
299 entry, err := uc.historyRepo.FindByURL(ctx, historyURL)303 entry, err := uc.historyRepo.FindByURL(ctx, historyURL)
M internal/infrastructure/webkit/webview.go +19 -3
@@ -1417,12 +1417,12 @@ func (wv *WebView) ResetForPoolReuse() {
14171417 wv.isLoading = false
14181418 wv.asyncCallbacks = nil
14191419 wv.runJSErrorStats = make(map[string]runJSErrorStat)
1420+ wv.lastProgressUpdate.Store(0)
14201421 wv.mu.Unlock()
14211422
14221423 wv.isFullscreen.Store(false)
14231424 wv.isPlayingAudio.Store(false)
14241425 wv.navigationActive.Store(false)
1425- wv.lastProgressUpdate.Store(0)
14261426
14271427 if wv.inner != nil {
14281428 wv.inner.StopLoading()
@@ -1561,6 +1561,16 @@ func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string)
15611561 log := logging.FromContext(ctx)
15621562
15631563 cb := gio.AsyncReadyCallback(func(_ uintptr, resPtr uintptr, _ uintptr) {
1564+ if wv.destroyed.Load() {
1565+ return
1566+ }
1567+ wv.mu.RLock()
1568+ inner := wv.inner
1569+ wv.mu.RUnlock()
1570+ if inner == nil {
1571+ return
1572+ }
1573+
15641574 domain := wv.runJSDomain()
15651575 if resPtr == 0 {
15661576 signature := "nil_async_result"
@@ -1577,7 +1587,7 @@ func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string)
15771587 }
15781588
15791589 res := &gio.AsyncResultBase{Ptr: resPtr}
1580- value, err := wv.inner.EvaluateJavascriptFinish(res)
1590+ value, err := inner.EvaluateJavascriptFinish(res)
15811591 if err != nil {
15821592 nonFatal, signature := classifyRunJSEvaluateError(err)
15831593 shouldLog, count := wv.shouldLogRunJSError(domain, signature, nonFatal, time.Now())
@@ -1629,7 +1639,13 @@ func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string)
16291639 if worldName != "" {
16301640 worldNamePtr = &worldName
16311641 }
1632- wv.inner.EvaluateJavascript(script, -1, worldNamePtr, nil, nil, &cb, 0)
1642+ wv.mu.RLock()
1643+ inner := wv.inner
1644+ wv.mu.RUnlock()
1645+ if inner == nil || wv.destroyed.Load() {
1646+ return
1647+ }
1648+ inner.EvaluateJavascript(script, -1, worldNamePtr, nil, nil, &cb, 0)
16331649 }
16341650
16351651 // AttachFrontend injects scripts/styles and wires the message router once per WebView.
@@ -1417,12 +1417,12 @@ func (wv *WebView) ResetForPoolReuse() {
1417 wv.isLoading = false1417 wv.isLoading = false
1418 wv.asyncCallbacks = nil1418 wv.asyncCallbacks = nil
1419 wv.runJSErrorStats = make(map[string]runJSErrorStat)1419 wv.runJSErrorStats = make(map[string]runJSErrorStat)
1420+ wv.lastProgressUpdate.Store(0)
1420 wv.mu.Unlock()1421 wv.mu.Unlock()
1421 1422
1422 wv.isFullscreen.Store(false)1423 wv.isFullscreen.Store(false)
1423 wv.isPlayingAudio.Store(false)1424 wv.isPlayingAudio.Store(false)
1424 wv.navigationActive.Store(false)1425 wv.navigationActive.Store(false)
1425- wv.lastProgressUpdate.Store(0)
1426 1426
1427 if wv.inner != nil {1427 if wv.inner != nil {
1428 wv.inner.StopLoading()1428 wv.inner.StopLoading()
@@ -1561,6 +1561,16 @@ func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string)
1561 log := logging.FromContext(ctx)1561 log := logging.FromContext(ctx)
1562 1562
1563 cb := gio.AsyncReadyCallback(func(_ uintptr, resPtr uintptr, _ uintptr) {1563 cb := gio.AsyncReadyCallback(func(_ uintptr, resPtr uintptr, _ uintptr) {
1564+ if wv.destroyed.Load() {
1565+ return
1566+ }
1567+ wv.mu.RLock()
1568+ inner := wv.inner
1569+ wv.mu.RUnlock()
1570+ if inner == nil {
1571+ return
1572+ }
1573+
1564 domain := wv.runJSDomain()1574 domain := wv.runJSDomain()
1565 if resPtr == 0 {1575 if resPtr == 0 {
1566 signature := "nil_async_result"1576 signature := "nil_async_result"
@@ -1577,7 +1587,7 @@ func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string)
1577 }1587 }
1578 1588
1579 res := &gio.AsyncResultBase{Ptr: resPtr}1589 res := &gio.AsyncResultBase{Ptr: resPtr}
1580- value, err := wv.inner.EvaluateJavascriptFinish(res)1590+ value, err := inner.EvaluateJavascriptFinish(res)
1581 if err != nil {1591 if err != nil {
1582 nonFatal, signature := classifyRunJSEvaluateError(err)1592 nonFatal, signature := classifyRunJSEvaluateError(err)
1583 shouldLog, count := wv.shouldLogRunJSError(domain, signature, nonFatal, time.Now())1593 shouldLog, count := wv.shouldLogRunJSError(domain, signature, nonFatal, time.Now())
@@ -1629,7 +1639,13 @@ func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string)
1629 if worldName != "" {1639 if worldName != "" {
1630 worldNamePtr = &worldName1640 worldNamePtr = &worldName
1631 }1641 }
1632- wv.inner.EvaluateJavascript(script, -1, worldNamePtr, nil, nil, &cb, 0)1642+ wv.mu.RLock()
1643+ inner := wv.inner
1644+ wv.mu.RUnlock()
1645+ if inner == nil || wv.destroyed.Load() {
1646+ return
1647+ }
1648+ inner.EvaluateJavascript(script, -1, worldNamePtr, nil, nil, &cb, 0)
1633 }1649 }
1634 1650
1635 // AttachFrontend injects scripts/styles and wires the message router once per WebView.1651 // AttachFrontend injects scripts/styles and wires the message router once per WebView.
M internal/ui/component/omnibox.go +5 -0
@@ -962,6 +962,8 @@ func (o *Omnibox) acceptGhostCompletion() {
962962 }
963963 o.isAcceptingGhost = true
964964 o.realInput = fullText
965+ o.selectedIndex = -1
966+ o.hasNavigated = false
965967 o.ghostToken++
966968 o.ghostSuffix = ""
967969 o.ghostFullText = ""
@@ -975,6 +977,9 @@ func (o *Omnibox) acceptGhostCompletion() {
975977 o.entry.SelectRegion(-1, -1)
976978 o.entry.SetPosition(-1)
977979 }
980+ if o.listBox != nil {
981+ o.listBox.SelectRow(nil)
982+ }
978983
979984 o.mu.Lock()
980985 o.isAcceptingGhost = false
@@ -962,6 +962,8 @@ func (o *Omnibox) acceptGhostCompletion() {
962 }962 }
963 o.isAcceptingGhost = true963 o.isAcceptingGhost = true
964 o.realInput = fullText964 o.realInput = fullText
965+ o.selectedIndex = -1
966+ o.hasNavigated = false
965 o.ghostToken++967 o.ghostToken++
966 o.ghostSuffix = ""968 o.ghostSuffix = ""
967 o.ghostFullText = ""969 o.ghostFullText = ""
@@ -975,6 +977,9 @@ func (o *Omnibox) acceptGhostCompletion() {
975 o.entry.SelectRegion(-1, -1)977 o.entry.SelectRegion(-1, -1)
976 o.entry.SetPosition(-1)978 o.entry.SetPosition(-1)
977 }979 }
980+ if o.listBox != nil {
981+ o.listBox.SelectRow(nil)
982+ }
978 983
979 o.mu.Lock()984 o.mu.Lock()
980 o.isAcceptingGhost = false985 o.isAcceptingGhost = false
M internal/ui/component/workspace_view_test.go +3 -3
@@ -166,7 +166,7 @@ func setupStackedLeafMocks(
166166 mockTitleBar.EXPECT().AddController(mock.Anything).Once()
167167
168168 // Close button click handler
169- mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint32(2)).Once()
169+ mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint(2)).Once()
170170
171171 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests
172172 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()
@@ -274,9 +274,9 @@ func TestSetActivePaneID_UpdatesStyling(t *testing.T) {
274274 mockStackBox2.EXPECT().SetVisible(true).Once()
275275 mockPaned.EXPECT().SetStartChild(mockStackBox1).Once()
276276 mockPaned.EXPECT().SetEndChild(mockStackBox2).Once()
277- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
277+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
278278 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
279- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
279+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
280280 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
281281
282282 mockBox.EXPECT().Append(mockPaned).Once()
@@ -166,7 +166,7 @@ func setupStackedLeafMocks(
166 mockTitleBar.EXPECT().AddController(mock.Anything).Once()166 mockTitleBar.EXPECT().AddController(mock.Anything).Once()
167 167
168 // Close button click handler168 // Close button click handler
169- mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint32(2)).Once()169+ mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint(2)).Once()
170 170
171 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests171 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests
172 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()172 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()
@@ -274,9 +274,9 @@ func TestSetActivePaneID_UpdatesStyling(t *testing.T) {
274 mockStackBox2.EXPECT().SetVisible(true).Once()274 mockStackBox2.EXPECT().SetVisible(true).Once()
275 mockPaned.EXPECT().SetStartChild(mockStackBox1).Once()275 mockPaned.EXPECT().SetStartChild(mockStackBox1).Once()
276 mockPaned.EXPECT().SetEndChild(mockStackBox2).Once()276 mockPaned.EXPECT().SetEndChild(mockStackBox2).Once()
277- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()277+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
278 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()278 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
279- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()279+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
280 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()280 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
281 281
282 mockBox.EXPECT().Append(mockPaned).Once()282 mockBox.EXPECT().Append(mockPaned).Once()
M internal/ui/layout/gtk_widgets.go +6 -6
@@ -159,18 +159,18 @@ func (p *gtkPaned) GetShrinkEndChild() bool { return p.inner.GetShrinkEndChil
159159 func (p *gtkPaned) SetWideHandle(wide bool) { p.inner.SetWideHandle(wide) }
160160 func (p *gtkPaned) GetWideHandle() bool { return p.inner.GetWideHandle() }
161161
162-func (p *gtkPaned) ConnectMap(callback func()) uint32 {
162+func (p *gtkPaned) ConnectMap(callback func()) uint {
163163 cb := func(_ gtk.Widget) {
164164 callback()
165165 }
166- return uint32(p.inner.ConnectMap(&cb))
166+ return p.inner.ConnectMap(&cb)
167167 }
168168
169-func (p *gtkPaned) ConnectNotifyPosition(callback func()) uint32 {
169+func (p *gtkPaned) ConnectNotifyPosition(callback func()) uint {
170170 cb := func(_ gobject.Object, _ uintptr) {
171171 callback()
172172 }
173- return uint32(p.inner.ConnectNotifyWithDetail("position", &cb))
173+ return p.inner.ConnectNotifyWithDetail("position", &cb)
174174 }
175175
176176 func (p *gtkPaned) AddTickCallback(callback func() bool) uint {
@@ -539,11 +539,11 @@ func (btn *gtkButton) GetChild() Widget {
539539 return &gtkWidget{inner: child}
540540 }
541541
542-func (btn *gtkButton) ConnectClicked(callback func()) uint32 {
542+func (btn *gtkButton) ConnectClicked(callback func()) uint {
543543 cb := func(_ gtk.Button) {
544544 callback()
545545 }
546- return uint32(btn.inner.ConnectClicked(&cb))
546+ return btn.inner.ConnectClicked(&cb)
547547 }
548548
549549 func (btn *gtkButton) GetAllocatedWidth() int { return btn.inner.GetAllocatedWidth() }
@@ -159,18 +159,18 @@ func (p *gtkPaned) GetShrinkEndChild() bool { return p.inner.GetShrinkEndChil
159 func (p *gtkPaned) SetWideHandle(wide bool) { p.inner.SetWideHandle(wide) }159 func (p *gtkPaned) SetWideHandle(wide bool) { p.inner.SetWideHandle(wide) }
160 func (p *gtkPaned) GetWideHandle() bool { return p.inner.GetWideHandle() }160 func (p *gtkPaned) GetWideHandle() bool { return p.inner.GetWideHandle() }
161 161
162-func (p *gtkPaned) ConnectMap(callback func()) uint32 {162+func (p *gtkPaned) ConnectMap(callback func()) uint {
163 cb := func(_ gtk.Widget) {163 cb := func(_ gtk.Widget) {
164 callback()164 callback()
165 }165 }
166- return uint32(p.inner.ConnectMap(&cb))166+ return p.inner.ConnectMap(&cb)
167 }167 }
168 168
169-func (p *gtkPaned) ConnectNotifyPosition(callback func()) uint32 {169+func (p *gtkPaned) ConnectNotifyPosition(callback func()) uint {
170 cb := func(_ gobject.Object, _ uintptr) {170 cb := func(_ gobject.Object, _ uintptr) {
171 callback()171 callback()
172 }172 }
173- return uint32(p.inner.ConnectNotifyWithDetail("position", &cb))173+ return p.inner.ConnectNotifyWithDetail("position", &cb)
174 }174 }
175 175
176 func (p *gtkPaned) AddTickCallback(callback func() bool) uint {176 func (p *gtkPaned) AddTickCallback(callback func() bool) uint {
@@ -539,11 +539,11 @@ func (btn *gtkButton) GetChild() Widget {
539 return &gtkWidget{inner: child}539 return &gtkWidget{inner: child}
540 }540 }
541 541
542-func (btn *gtkButton) ConnectClicked(callback func()) uint32 {542+func (btn *gtkButton) ConnectClicked(callback func()) uint {
543 cb := func(_ gtk.Button) {543 cb := func(_ gtk.Button) {
544 callback()544 callback()
545 }545 }
546- return uint32(btn.inner.ConnectClicked(&cb))546+ return btn.inner.ConnectClicked(&cb)
547 }547 }
548 548
549 func (btn *gtkButton) GetAllocatedWidth() int { return btn.inner.GetAllocatedWidth() }549 func (btn *gtkButton) GetAllocatedWidth() int { return btn.inner.GetAllocatedWidth() }
M internal/ui/layout/mocks/mocks.go +18 -18
@@ -1485,18 +1485,18 @@ func (_c *MockPanedWidget_ComputePoint_Call) RunAndReturn(run func(target layout
14851485 }
14861486
14871487 // ConnectMap provides a mock function for the type MockPanedWidget
1488-func (_mock *MockPanedWidget) ConnectMap(callback func()) uint32 {
1488+func (_mock *MockPanedWidget) ConnectMap(callback func()) uint {
14891489 ret := _mock.Called(callback)
14901490
14911491 if len(ret) == 0 {
14921492 panic("no return value specified for ConnectMap")
14931493 }
14941494
1495- var r0 uint32
1496- if returnFunc, ok := ret.Get(0).(func(func()) uint32); ok {
1495+ var r0 uint
1496+ if returnFunc, ok := ret.Get(0).(func(func()) uint); ok {
14971497 r0 = returnFunc(callback)
14981498 } else {
1499- r0 = ret.Get(0).(uint32)
1499+ r0 = ret.Get(0).(uint)
15001500 }
15011501 return r0
15021502 }
@@ -1525,29 +1525,29 @@ func (_c *MockPanedWidget_ConnectMap_Call) Run(run func(callback func())) *MockP
15251525 return _c
15261526 }
15271527
1528-func (_c *MockPanedWidget_ConnectMap_Call) Return(v uint32) *MockPanedWidget_ConnectMap_Call {
1528+func (_c *MockPanedWidget_ConnectMap_Call) Return(v uint) *MockPanedWidget_ConnectMap_Call {
15291529 _c.Call.Return(v)
15301530 return _c
15311531 }
15321532
1533-func (_c *MockPanedWidget_ConnectMap_Call) RunAndReturn(run func(callback func()) uint32) *MockPanedWidget_ConnectMap_Call {
1533+func (_c *MockPanedWidget_ConnectMap_Call) RunAndReturn(run func(callback func()) uint) *MockPanedWidget_ConnectMap_Call {
15341534 _c.Call.Return(run)
15351535 return _c
15361536 }
15371537
15381538 // ConnectNotifyPosition provides a mock function for the type MockPanedWidget
1539-func (_mock *MockPanedWidget) ConnectNotifyPosition(callback func()) uint32 {
1539+func (_mock *MockPanedWidget) ConnectNotifyPosition(callback func()) uint {
15401540 ret := _mock.Called(callback)
15411541
15421542 if len(ret) == 0 {
15431543 panic("no return value specified for ConnectNotifyPosition")
15441544 }
15451545
1546- var r0 uint32
1547- if returnFunc, ok := ret.Get(0).(func(func()) uint32); ok {
1546+ var r0 uint
1547+ if returnFunc, ok := ret.Get(0).(func(func()) uint); ok {
15481548 r0 = returnFunc(callback)
15491549 } else {
1550- r0 = ret.Get(0).(uint32)
1550+ r0 = ret.Get(0).(uint)
15511551 }
15521552 return r0
15531553 }
@@ -1576,12 +1576,12 @@ func (_c *MockPanedWidget_ConnectNotifyPosition_Call) Run(run func(callback func
15761576 return _c
15771577 }
15781578
1579-func (_c *MockPanedWidget_ConnectNotifyPosition_Call) Return(v uint32) *MockPanedWidget_ConnectNotifyPosition_Call {
1579+func (_c *MockPanedWidget_ConnectNotifyPosition_Call) Return(v uint) *MockPanedWidget_ConnectNotifyPosition_Call {
15801580 _c.Call.Return(v)
15811581 return _c
15821582 }
15831583
1584-func (_c *MockPanedWidget_ConnectNotifyPosition_Call) RunAndReturn(run func(callback func()) uint32) *MockPanedWidget_ConnectNotifyPosition_Call {
1584+func (_c *MockPanedWidget_ConnectNotifyPosition_Call) RunAndReturn(run func(callback func()) uint) *MockPanedWidget_ConnectNotifyPosition_Call {
15851585 _c.Call.Return(run)
15861586 return _c
15871587 }
@@ -8007,18 +8007,18 @@ func (_c *MockButtonWidget_ComputePoint_Call) RunAndReturn(run func(target layou
80078007 }
80088008
80098009 // ConnectClicked provides a mock function for the type MockButtonWidget
8010-func (_mock *MockButtonWidget) ConnectClicked(callback func()) uint32 {
8010+func (_mock *MockButtonWidget) ConnectClicked(callback func()) uint {
80118011 ret := _mock.Called(callback)
80128012
80138013 if len(ret) == 0 {
80148014 panic("no return value specified for ConnectClicked")
80158015 }
80168016
8017- var r0 uint32
8018- if returnFunc, ok := ret.Get(0).(func(func()) uint32); ok {
8017+ var r0 uint
8018+ if returnFunc, ok := ret.Get(0).(func(func()) uint); ok {
80198019 r0 = returnFunc(callback)
80208020 } else {
8021- r0 = ret.Get(0).(uint32)
8021+ r0 = ret.Get(0).(uint)
80228022 }
80238023 return r0
80248024 }
@@ -8047,12 +8047,12 @@ func (_c *MockButtonWidget_ConnectClicked_Call) Run(run func(callback func())) *
80478047 return _c
80488048 }
80498049
8050-func (_c *MockButtonWidget_ConnectClicked_Call) Return(v uint32) *MockButtonWidget_ConnectClicked_Call {
8050+func (_c *MockButtonWidget_ConnectClicked_Call) Return(v uint) *MockButtonWidget_ConnectClicked_Call {
80518051 _c.Call.Return(v)
80528052 return _c
80538053 }
80548054
8055-func (_c *MockButtonWidget_ConnectClicked_Call) RunAndReturn(run func(callback func()) uint32) *MockButtonWidget_ConnectClicked_Call {
8055+func (_c *MockButtonWidget_ConnectClicked_Call) RunAndReturn(run func(callback func()) uint) *MockButtonWidget_ConnectClicked_Call {
80568056 _c.Call.Return(run)
80578057 return _c
80588058 }
@@ -1485,18 +1485,18 @@ func (_c *MockPanedWidget_ComputePoint_Call) RunAndReturn(run func(target layout
1485 }1485 }
1486 1486
1487 // ConnectMap provides a mock function for the type MockPanedWidget1487 // ConnectMap provides a mock function for the type MockPanedWidget
1488-func (_mock *MockPanedWidget) ConnectMap(callback func()) uint32 {1488+func (_mock *MockPanedWidget) ConnectMap(callback func()) uint {
1489 ret := _mock.Called(callback)1489 ret := _mock.Called(callback)
1490 1490
1491 if len(ret) == 0 {1491 if len(ret) == 0 {
1492 panic("no return value specified for ConnectMap")1492 panic("no return value specified for ConnectMap")
1493 }1493 }
1494 1494
1495- var r0 uint321495+ var r0 uint
1496- if returnFunc, ok := ret.Get(0).(func(func()) uint32); ok {1496+ if returnFunc, ok := ret.Get(0).(func(func()) uint); ok {
1497 r0 = returnFunc(callback)1497 r0 = returnFunc(callback)
1498 } else {1498 } else {
1499- r0 = ret.Get(0).(uint32)1499+ r0 = ret.Get(0).(uint)
1500 }1500 }
1501 return r01501 return r0
1502 }1502 }
@@ -1525,29 +1525,29 @@ func (_c *MockPanedWidget_ConnectMap_Call) Run(run func(callback func())) *MockP
1525 return _c1525 return _c
1526 }1526 }
1527 1527
1528-func (_c *MockPanedWidget_ConnectMap_Call) Return(v uint32) *MockPanedWidget_ConnectMap_Call {1528+func (_c *MockPanedWidget_ConnectMap_Call) Return(v uint) *MockPanedWidget_ConnectMap_Call {
1529 _c.Call.Return(v)1529 _c.Call.Return(v)
1530 return _c1530 return _c
1531 }1531 }
1532 1532
1533-func (_c *MockPanedWidget_ConnectMap_Call) RunAndReturn(run func(callback func()) uint32) *MockPanedWidget_ConnectMap_Call {1533+func (_c *MockPanedWidget_ConnectMap_Call) RunAndReturn(run func(callback func()) uint) *MockPanedWidget_ConnectMap_Call {
1534 _c.Call.Return(run)1534 _c.Call.Return(run)
1535 return _c1535 return _c
1536 }1536 }
1537 1537
1538 // ConnectNotifyPosition provides a mock function for the type MockPanedWidget1538 // ConnectNotifyPosition provides a mock function for the type MockPanedWidget
1539-func (_mock *MockPanedWidget) ConnectNotifyPosition(callback func()) uint32 {1539+func (_mock *MockPanedWidget) ConnectNotifyPosition(callback func()) uint {
1540 ret := _mock.Called(callback)1540 ret := _mock.Called(callback)
1541 1541
1542 if len(ret) == 0 {1542 if len(ret) == 0 {
1543 panic("no return value specified for ConnectNotifyPosition")1543 panic("no return value specified for ConnectNotifyPosition")
1544 }1544 }
1545 1545
1546- var r0 uint321546+ var r0 uint
1547- if returnFunc, ok := ret.Get(0).(func(func()) uint32); ok {1547+ if returnFunc, ok := ret.Get(0).(func(func()) uint); ok {
1548 r0 = returnFunc(callback)1548 r0 = returnFunc(callback)
1549 } else {1549 } else {
1550- r0 = ret.Get(0).(uint32)1550+ r0 = ret.Get(0).(uint)
1551 }1551 }
1552 return r01552 return r0
1553 }1553 }
@@ -1576,12 +1576,12 @@ func (_c *MockPanedWidget_ConnectNotifyPosition_Call) Run(run func(callback func
1576 return _c1576 return _c
1577 }1577 }
1578 1578
1579-func (_c *MockPanedWidget_ConnectNotifyPosition_Call) Return(v uint32) *MockPanedWidget_ConnectNotifyPosition_Call {1579+func (_c *MockPanedWidget_ConnectNotifyPosition_Call) Return(v uint) *MockPanedWidget_ConnectNotifyPosition_Call {
1580 _c.Call.Return(v)1580 _c.Call.Return(v)
1581 return _c1581 return _c
1582 }1582 }
1583 1583
1584-func (_c *MockPanedWidget_ConnectNotifyPosition_Call) RunAndReturn(run func(callback func()) uint32) *MockPanedWidget_ConnectNotifyPosition_Call {1584+func (_c *MockPanedWidget_ConnectNotifyPosition_Call) RunAndReturn(run func(callback func()) uint) *MockPanedWidget_ConnectNotifyPosition_Call {
1585 _c.Call.Return(run)1585 _c.Call.Return(run)
1586 return _c1586 return _c
1587 }1587 }
@@ -8007,18 +8007,18 @@ func (_c *MockButtonWidget_ComputePoint_Call) RunAndReturn(run func(target layou
8007 }8007 }
8008 8008
8009 // ConnectClicked provides a mock function for the type MockButtonWidget8009 // ConnectClicked provides a mock function for the type MockButtonWidget
8010-func (_mock *MockButtonWidget) ConnectClicked(callback func()) uint32 {8010+func (_mock *MockButtonWidget) ConnectClicked(callback func()) uint {
8011 ret := _mock.Called(callback)8011 ret := _mock.Called(callback)
8012 8012
8013 if len(ret) == 0 {8013 if len(ret) == 0 {
8014 panic("no return value specified for ConnectClicked")8014 panic("no return value specified for ConnectClicked")
8015 }8015 }
8016 8016
8017- var r0 uint328017+ var r0 uint
8018- if returnFunc, ok := ret.Get(0).(func(func()) uint32); ok {8018+ if returnFunc, ok := ret.Get(0).(func(func()) uint); ok {
8019 r0 = returnFunc(callback)8019 r0 = returnFunc(callback)
8020 } else {8020 } else {
8021- r0 = ret.Get(0).(uint32)8021+ r0 = ret.Get(0).(uint)
8022 }8022 }
8023 return r08023 return r0
8024 }8024 }
@@ -8047,12 +8047,12 @@ func (_c *MockButtonWidget_ConnectClicked_Call) Run(run func(callback func())) *
8047 return _c8047 return _c
8048 }8048 }
8049 8049
8050-func (_c *MockButtonWidget_ConnectClicked_Call) Return(v uint32) *MockButtonWidget_ConnectClicked_Call {8050+func (_c *MockButtonWidget_ConnectClicked_Call) Return(v uint) *MockButtonWidget_ConnectClicked_Call {
8051 _c.Call.Return(v)8051 _c.Call.Return(v)
8052 return _c8052 return _c
8053 }8053 }
8054 8054
8055-func (_c *MockButtonWidget_ConnectClicked_Call) RunAndReturn(run func(callback func()) uint32) *MockButtonWidget_ConnectClicked_Call {8055+func (_c *MockButtonWidget_ConnectClicked_Call) RunAndReturn(run func(callback func()) uint) *MockButtonWidget_ConnectClicked_Call {
8056 _c.Call.Return(run)8056 _c.Call.Return(run)
8057 return _c8057 return _c
8058 }8058 }
M internal/ui/layout/split_test.go +2 -2
@@ -29,10 +29,10 @@ func setupSplitViewMocks(mockPaned *mocks.MockPanedWidget, orientation layout.Or
2929 mockPaned.EXPECT().GetAllocatedHeight().Return(0).Once()
3030 }
3131
32- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
32+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
3333
3434 // Since allocation is 0, ApplyRatio returns false and callbacks are registered
35- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
35+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
3636 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
3737 }
3838
@@ -29,10 +29,10 @@ func setupSplitViewMocks(mockPaned *mocks.MockPanedWidget, orientation layout.Or
29 mockPaned.EXPECT().GetAllocatedHeight().Return(0).Once()29 mockPaned.EXPECT().GetAllocatedHeight().Return(0).Once()
30 }30 }
31 31
32- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()32+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
33 33
34 // Since allocation is 0, ApplyRatio returns false and callbacks are registered34 // Since allocation is 0, ApplyRatio returns false and callbacks are registered
35- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()35+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
36 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()36 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
37 }37 }
38 38
M internal/ui/layout/stacked.go +4 -4
@@ -35,7 +35,7 @@ type stackedPane struct {
3535 isActive bool
3636
3737 // Signal handler IDs for cleanup on removal
38- closeClickSignalID uint32
38+ closeClickSignalID uint
3939 closeButton ButtonWidget // stored for signal disconnection
4040
4141 // Retained callback for GestureClick to prevent GC
@@ -183,7 +183,7 @@ func (sv *StackedView) AddPane(ctx context.Context, paneID, title, faviconIconNa
183183 // Returns the retained callback (to prevent GC) and close signal ID for disconnection.
184184 func (sv *StackedView) connectTitleBarHandlers(
185185 tb titleBarComponents, paneID string,
186-) (titleClickCallback interface{}, closeSignalID uint32) {
186+) (titleClickCallback interface{}, closeSignalID uint) {
187187 // Connect title bar click handler using GestureClick
188188 // This prevents event propagation issues with nested buttons
189189 clickCtrl := gtk.NewGestureClick()
@@ -259,7 +259,7 @@ func (sv *StackedView) disconnectPaneSignals(pane *stackedPane) {
259259
260260 // disconnectButtonSignal safely disconnects a signal from a button widget.
261261 // Returns silently if button is nil, signal ID is 0, or widget doesn't support GTK operations.
262-func disconnectButtonSignal(btn ButtonWidget, signalID uint32) {
262+func disconnectButtonSignal(btn ButtonWidget, signalID uint) {
263263 if btn == nil || signalID == 0 {
264264 return
265265 }
@@ -275,7 +275,7 @@ func disconnectButtonSignal(btn ButtonWidget, signalID uint32) {
275275 }
276276
277277 obj := gobject.ObjectNewFromInternalPtr(ptr)
278- gobject.SignalHandlerDisconnect(obj, uint(signalID))
278+ gobject.SignalHandlerDisconnect(obj, signalID)
279279 }
280280
281281 // InsertPaneAfter inserts a new pane after the specified index position.
@@ -35,7 +35,7 @@ type stackedPane struct {
35 isActive bool35 isActive bool
36 36
37 // Signal handler IDs for cleanup on removal37 // Signal handler IDs for cleanup on removal
38- closeClickSignalID uint3238+ closeClickSignalID uint
39 closeButton ButtonWidget // stored for signal disconnection39 closeButton ButtonWidget // stored for signal disconnection
40 40
41 // Retained callback for GestureClick to prevent GC41 // Retained callback for GestureClick to prevent GC
@@ -183,7 +183,7 @@ func (sv *StackedView) AddPane(ctx context.Context, paneID, title, faviconIconNa
183 // Returns the retained callback (to prevent GC) and close signal ID for disconnection.183 // Returns the retained callback (to prevent GC) and close signal ID for disconnection.
184 func (sv *StackedView) connectTitleBarHandlers(184 func (sv *StackedView) connectTitleBarHandlers(
185 tb titleBarComponents, paneID string,185 tb titleBarComponents, paneID string,
186-) (titleClickCallback interface{}, closeSignalID uint32) {186+) (titleClickCallback interface{}, closeSignalID uint) {
187 // Connect title bar click handler using GestureClick187 // Connect title bar click handler using GestureClick
188 // This prevents event propagation issues with nested buttons188 // This prevents event propagation issues with nested buttons
189 clickCtrl := gtk.NewGestureClick()189 clickCtrl := gtk.NewGestureClick()
@@ -259,7 +259,7 @@ func (sv *StackedView) disconnectPaneSignals(pane *stackedPane) {
259 259
260 // disconnectButtonSignal safely disconnects a signal from a button widget.260 // disconnectButtonSignal safely disconnects a signal from a button widget.
261 // Returns silently if button is nil, signal ID is 0, or widget doesn't support GTK operations.261 // Returns silently if button is nil, signal ID is 0, or widget doesn't support GTK operations.
262-func disconnectButtonSignal(btn ButtonWidget, signalID uint32) {262+func disconnectButtonSignal(btn ButtonWidget, signalID uint) {
263 if btn == nil || signalID == 0 {263 if btn == nil || signalID == 0 {
264 return264 return
265 }265 }
@@ -275,7 +275,7 @@ func disconnectButtonSignal(btn ButtonWidget, signalID uint32) {
275 }275 }
276 276
277 obj := gobject.ObjectNewFromInternalPtr(ptr)277 obj := gobject.ObjectNewFromInternalPtr(ptr)
278- gobject.SignalHandlerDisconnect(obj, uint(signalID))278+ gobject.SignalHandlerDisconnect(obj, signalID)
279 }279 }
280 280
281 // InsertPaneAfter inserts a new pane after the specified index position.281 // InsertPaneAfter inserts a new pane after the specified index position.
M internal/ui/layout/stacked_test.go +2 -2
@@ -70,7 +70,7 @@ func setupPaneMocks(t *testing.T, mockFactory *mocks.MockWidgetFactory, mockBox
7070 mockTitleBar.EXPECT().AddController(mock.Anything).Once()
7171
7272 // Close button click handler
73- mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint32(2)).Once()
73+ mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint(2)).Once()
7474
7575 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests
7676 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()
@@ -593,7 +593,7 @@ func setupInsertPaneMocks(
593593 mockTitleBar.EXPECT().AddController(mock.Anything).Once()
594594
595595 // Close button click handler
596- mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint32(2)).Once()
596+ mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint(2)).Once()
597597
598598 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests
599599 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()
@@ -70,7 +70,7 @@ func setupPaneMocks(t *testing.T, mockFactory *mocks.MockWidgetFactory, mockBox
70 mockTitleBar.EXPECT().AddController(mock.Anything).Once()70 mockTitleBar.EXPECT().AddController(mock.Anything).Once()
71 71
72 // Close button click handler72 // Close button click handler
73- mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint32(2)).Once()73+ mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint(2)).Once()
74 74
75 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests75 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests
76 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()76 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()
@@ -593,7 +593,7 @@ func setupInsertPaneMocks(
593 mockTitleBar.EXPECT().AddController(mock.Anything).Once()593 mockTitleBar.EXPECT().AddController(mock.Anything).Once()
594 594
595 // Close button click handler595 // Close button click handler
596- mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint32(2)).Once()596+ mockCloseButton.EXPECT().ConnectClicked(mock.Anything).Return(uint(2)).Once()
597 597
598 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests598 // Signal disconnection calls GtkWidget() - return nil to skip actual GTK operations in tests
599 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()599 mockCloseButton.EXPECT().GtkWidget().Return(nil).Maybe()
M internal/ui/layout/tree_test.go +12 -12
@@ -122,9 +122,9 @@ func TestBuild_HorizontalSplit(t *testing.T) {
122122 mockRightStackBox.EXPECT().SetVisible(true).Once()
123123 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()
124124 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()
125- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
125+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
126126 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
127- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
127+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
128128 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
129129
130130 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -172,9 +172,9 @@ func TestBuild_VerticalSplit(t *testing.T) {
172172 mockBottomStackBox.EXPECT().SetVisible(true).Once()
173173 mockPaned.EXPECT().SetStartChild(mockTopStackBox).Once()
174174 mockPaned.EXPECT().SetEndChild(mockBottomStackBox).Once()
175- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
175+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
176176 mockPaned.EXPECT().GetAllocatedHeight().Return(0).Once()
177- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
177+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
178178 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
179179
180180 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -241,9 +241,9 @@ func TestBuild_NestedSplits(t *testing.T) {
241241 mockStackBox2.EXPECT().SetVisible(true).Once()
242242 mockInnerPaned.EXPECT().SetStartChild(mockStackBox1).Once()
243243 mockInnerPaned.EXPECT().SetEndChild(mockStackBox2).Once()
244- mockInnerPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
244+ mockInnerPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
245245 mockInnerPaned.EXPECT().GetAllocatedHeight().Return(0).Once()
246- mockInnerPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
246+ mockInnerPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
247247 mockInnerPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
248248
249249 // Outer split (horizontal) gets inner paned and pane3
@@ -255,9 +255,9 @@ func TestBuild_NestedSplits(t *testing.T) {
255255 mockStackBox3.EXPECT().SetVisible(true).Once()
256256 mockOuterPaned.EXPECT().SetStartChild(mockInnerPaned).Once()
257257 mockOuterPaned.EXPECT().SetEndChild(mockStackBox3).Once()
258- mockOuterPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
258+ mockOuterPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
259259 mockOuterPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
260- mockOuterPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
260+ mockOuterPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
261261 mockOuterPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
262262
263263 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -417,9 +417,9 @@ func TestGetNodeIDs_ReturnsAllIDs(t *testing.T) {
417417 mockRightStackBox.EXPECT().SetVisible(true).Once()
418418 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()
419419 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()
420- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
420+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
421421 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
422- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
422+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
423423 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
424424
425425 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -542,9 +542,9 @@ func TestUpdateSplitRatio_ExistingNode(t *testing.T) {
542542 mockRightStackBox.EXPECT().SetVisible(true).Once()
543543 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()
544544 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()
545- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()
545+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
546546 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Twice()
547- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()
547+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
548548
549549 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
550550
@@ -122,9 +122,9 @@ func TestBuild_HorizontalSplit(t *testing.T) {
122 mockRightStackBox.EXPECT().SetVisible(true).Once()122 mockRightStackBox.EXPECT().SetVisible(true).Once()
123 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()123 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()
124 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()124 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()
125- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()125+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
126 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()126 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
127- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()127+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
128 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()128 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
129 129
130 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)130 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -172,9 +172,9 @@ func TestBuild_VerticalSplit(t *testing.T) {
172 mockBottomStackBox.EXPECT().SetVisible(true).Once()172 mockBottomStackBox.EXPECT().SetVisible(true).Once()
173 mockPaned.EXPECT().SetStartChild(mockTopStackBox).Once()173 mockPaned.EXPECT().SetStartChild(mockTopStackBox).Once()
174 mockPaned.EXPECT().SetEndChild(mockBottomStackBox).Once()174 mockPaned.EXPECT().SetEndChild(mockBottomStackBox).Once()
175- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()175+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
176 mockPaned.EXPECT().GetAllocatedHeight().Return(0).Once()176 mockPaned.EXPECT().GetAllocatedHeight().Return(0).Once()
177- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()177+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
178 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()178 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
179 179
180 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)180 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -241,9 +241,9 @@ func TestBuild_NestedSplits(t *testing.T) {
241 mockStackBox2.EXPECT().SetVisible(true).Once()241 mockStackBox2.EXPECT().SetVisible(true).Once()
242 mockInnerPaned.EXPECT().SetStartChild(mockStackBox1).Once()242 mockInnerPaned.EXPECT().SetStartChild(mockStackBox1).Once()
243 mockInnerPaned.EXPECT().SetEndChild(mockStackBox2).Once()243 mockInnerPaned.EXPECT().SetEndChild(mockStackBox2).Once()
244- mockInnerPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()244+ mockInnerPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
245 mockInnerPaned.EXPECT().GetAllocatedHeight().Return(0).Once()245 mockInnerPaned.EXPECT().GetAllocatedHeight().Return(0).Once()
246- mockInnerPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()246+ mockInnerPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
247 mockInnerPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()247 mockInnerPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
248 248
249 // Outer split (horizontal) gets inner paned and pane3249 // Outer split (horizontal) gets inner paned and pane3
@@ -255,9 +255,9 @@ func TestBuild_NestedSplits(t *testing.T) {
255 mockStackBox3.EXPECT().SetVisible(true).Once()255 mockStackBox3.EXPECT().SetVisible(true).Once()
256 mockOuterPaned.EXPECT().SetStartChild(mockInnerPaned).Once()256 mockOuterPaned.EXPECT().SetStartChild(mockInnerPaned).Once()
257 mockOuterPaned.EXPECT().SetEndChild(mockStackBox3).Once()257 mockOuterPaned.EXPECT().SetEndChild(mockStackBox3).Once()
258- mockOuterPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()258+ mockOuterPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
259 mockOuterPaned.EXPECT().GetAllocatedWidth().Return(0).Once()259 mockOuterPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
260- mockOuterPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()260+ mockOuterPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
261 mockOuterPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()261 mockOuterPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
262 262
263 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)263 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -417,9 +417,9 @@ func TestGetNodeIDs_ReturnsAllIDs(t *testing.T) {
417 mockRightStackBox.EXPECT().SetVisible(true).Once()417 mockRightStackBox.EXPECT().SetVisible(true).Once()
418 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()418 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()
419 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()419 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()
420- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()420+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
421 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()421 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Once()
422- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()422+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
423 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()423 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
424 424
425 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)425 renderer := layout.NewTreeRenderer(ctx, mockFactory, mockPaneViewFactory)
@@ -542,9 +542,9 @@ func TestUpdateSplitRatio_ExistingNode(t *testing.T) {
542 mockRightStackBox.EXPECT().SetVisible(true).Once()542 mockRightStackBox.EXPECT().SetVisible(true).Once()
543 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()543 mockPaned.EXPECT().SetStartChild(mockLeftStackBox).Once()
544 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()544 mockPaned.EXPECT().SetEndChild(mockRightStackBox).Once()
545- mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint32(0)).Once()545+ mockPaned.EXPECT().ConnectNotifyPosition(mock.Anything).Return(uint(0)).Once()
546 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Twice()546 mockPaned.EXPECT().GetAllocatedWidth().Return(0).Twice()
547- mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint32(0)).Once()547+ mockPaned.EXPECT().ConnectMap(mock.Anything).Return(uint(0)).Once()
548 548
549 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()549 mockPaned.EXPECT().AddTickCallback(mock.Anything).Return(uint(0)).Once()
550 550
M internal/ui/layout/widgets.go +3 -3
@@ -95,8 +95,8 @@ type PanedWidget interface {
9595 GetShrinkEndChild() bool
9696
9797 // Signals
98- ConnectMap(callback func()) uint32
99- ConnectNotifyPosition(callback func()) uint32
98+ ConnectMap(callback func()) uint
99+ ConnectNotifyPosition(callback func()) uint
100100
101101 // Tick callback for frame-based updates (returns signal ID)
102102 // Callback returns true to continue, false to stop
@@ -182,7 +182,7 @@ type ButtonWidget interface {
182182 SetIconName(iconName string)
183183
184184 // Connect click handler, returns signal ID for disconnection
185- ConnectClicked(callback func()) uint32
185+ ConnectClicked(callback func()) uint
186186 }
187187
188188 // Paintable represents a graphics texture that can be displayed in an image.
@@ -95,8 +95,8 @@ type PanedWidget interface {
95 GetShrinkEndChild() bool95 GetShrinkEndChild() bool
96 96
97 // Signals97 // Signals
98- ConnectMap(callback func()) uint3298+ ConnectMap(callback func()) uint
99- ConnectNotifyPosition(callback func()) uint3299+ ConnectNotifyPosition(callback func()) uint
100 100
101 // Tick callback for frame-based updates (returns signal ID)101 // Tick callback for frame-based updates (returns signal ID)
102 // Callback returns true to continue, false to stop102 // Callback returns true to continue, false to stop
@@ -182,7 +182,7 @@ type ButtonWidget interface {
182 SetIconName(iconName string)182 SetIconName(iconName string)
183 183
184 // Connect click handler, returns signal ID for disconnection184 // Connect click handler, returns signal ID for disconnection
185- ConnectClicked(callback func()) uint32185+ ConnectClicked(callback func()) uint
186 }186 }
187 187
188 // Paintable represents a graphics texture that can be displayed in an image.188 // Paintable represents a graphics texture that can be displayed in an image.

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