@@ -193,23 +193,46 @@ func (app *App) setTrayTitle() {
193193 // Set title and icon based on PR state
194194 var title string
195195 var iconType IconType
196- switch {
197- case counts .IncomingBlocked == 0 && counts .OutgoingBlocked == 0 :
198- title = ""
199- iconType = IconSmiling
200- case counts .IncomingBlocked > 0 && counts .OutgoingBlocked > 0 :
201- title = fmt .Sprintf ("%d / %d" , counts .IncomingBlocked , counts .OutgoingBlocked )
202- iconType = IconBoth
203- case counts .IncomingBlocked > 0 :
204- title = fmt .Sprintf ("%d" , counts .IncomingBlocked )
205- iconType = IconGoose
206- default :
207- title = fmt .Sprintf ("%d" , counts .OutgoingBlocked )
208- iconType = IconPopper
196+
197+ // On Linux, always show counts if there are any PRs
198+ // This helps since not all desktop environments show the text
199+ if runtime .GOOS == "linux" && (counts .IncomingTotal > 0 || counts .OutgoingTotal > 0 ) {
200+ // Show blocked/total format for better visibility
201+ if counts .IncomingBlocked > 0 && counts .OutgoingBlocked > 0 {
202+ title = fmt .Sprintf ("%d/%d • %d/%d" , counts .IncomingBlocked , counts .IncomingTotal , counts .OutgoingBlocked , counts .OutgoingTotal )
203+ iconType = IconBoth
204+ } else if counts .IncomingBlocked > 0 {
205+ title = fmt .Sprintf ("%d/%d" , counts .IncomingBlocked , counts .IncomingTotal )
206+ iconType = IconGoose
207+ } else if counts .OutgoingBlocked > 0 {
208+ title = fmt .Sprintf ("%d/%d" , counts .OutgoingBlocked , counts .OutgoingTotal )
209+ iconType = IconPopper
210+ } else {
211+ // No blocked PRs but there are PRs
212+ title = fmt .Sprintf ("0/%d" , counts .IncomingTotal + counts .OutgoingTotal )
213+ iconType = IconSmiling
214+ }
215+ } else {
216+ // Original behavior for other platforms
217+ switch {
218+ case counts .IncomingBlocked == 0 && counts .OutgoingBlocked == 0 :
219+ title = ""
220+ iconType = IconSmiling
221+ case counts .IncomingBlocked > 0 && counts .OutgoingBlocked > 0 :
222+ title = fmt .Sprintf ("%d / %d" , counts .IncomingBlocked , counts .OutgoingBlocked )
223+ iconType = IconBoth
224+ case counts .IncomingBlocked > 0 :
225+ title = fmt .Sprintf ("%d" , counts .IncomingBlocked )
226+ iconType = IconGoose
227+ default :
228+ title = fmt .Sprintf ("%d" , counts .OutgoingBlocked )
229+ iconType = IconPopper
230+ }
209231 }
210232
211233 // Log title change with detailed counts
212- slog .Debug ("[TRAY] Setting title and icon" ,
234+ slog .Info ("[TRAY] Setting title and icon" ,
235+ "os" , runtime .GOOS ,
213236 "title" , title ,
214237 "icon" , iconType ,
215238 "incoming_total" , counts .IncomingTotal ,
@@ -533,9 +556,17 @@ func (app *App) generatePRSectionTitles(prs []PR, sectionTitle string, hiddenOrg
533556// rebuildMenu completely rebuilds the menu from scratch.
534557func (app * App ) rebuildMenu (ctx context.Context ) {
535558 // Rebuild entire menu
559+ slog .Info ("[MENU] Starting rebuildMenu" , "os" , runtime .GOOS )
536560
537561 // Clear all existing menu items
538562 app .systrayInterface .ResetMenu ()
563+ slog .Info ("[MENU] Called ResetMenu" )
564+
565+ // On Linux, add a small delay to ensure DBus properly processes the reset
566+ // This helps prevent menu item duplication
567+ if runtime .GOOS == "linux" {
568+ time .Sleep (50 * time .Millisecond )
569+ }
539570
540571 // Check for errors (auth or connection failures)
541572 app .mu .RLock ()
0 commit comments