@@ -33,10 +33,13 @@ impl App {
3333
3434 fn build_workspace_root ( & mut self , sender : ComponentSender < Self > ) {
3535 let tab_view = adw:: TabView :: new ( ) ;
36+ // Content-sized tabs: with expand_tabs(true), 5 tabs already span the
37+ // whole bar and 15+ would compress to unreadable widths. Matches
38+ // TablePlus / DBeaver / DataGrip; AdwTabBar handles overflow natively.
3639 let tab_bar = adw:: TabBar :: builder ( )
3740 . view ( & tab_view)
3841 . autohide ( false )
39- . expand_tabs ( true )
42+ . expand_tabs ( false )
4043 . build ( ) ;
4144
4245 let overview_button = adw:: TabButton :: builder ( )
@@ -123,7 +126,8 @@ impl App {
123126 . count ( ) ;
124127 let label = default_editor_tab_label ( editor_count + 1 ) ;
125128 page. set_title ( & label) ;
126- page. set_tooltip ( & label) ;
129+ // Empty query → no tooltip; tooltip will be set on first edit
130+ // via on_editor_tab_query_changed.
127131 write_workspace_tab_id ( & page, tab_id) ;
128132 let slot = EditorTabSlot {
129133 id : tab_id,
@@ -317,7 +321,9 @@ impl App {
317321 let page = tab_view. append ( controller. widget ( ) ) ;
318322 let label = qualified_browse_tab_label ( self . sidebar_schemas_distinct ( ) , schema. as_deref ( ) , & table) ;
319323 page. set_title ( & label) ;
320- page. set_tooltip ( & label) ;
324+ if let Some ( tip) = browse_tab_tooltip ( schema. as_deref ( ) , & table, & label) {
325+ page. set_tooltip ( & tip) ;
326+ }
321327 write_workspace_tab_id ( & page, tab_id) ;
322328
323329 let slot = BrowseTabSlot {
@@ -359,7 +365,9 @@ impl App {
359365 false => derive_tab_label ( & query) ,
360366 } ;
361367 page. set_title ( & label) ;
362- page. set_tooltip ( & label) ;
368+ if let Some ( tip) = editor_tab_tooltip ( & query, & label) {
369+ page. set_tooltip ( & tip) ;
370+ }
363371 write_workspace_tab_id ( & page, tab_id) ;
364372
365373 let slot = EditorTabSlot {
@@ -632,7 +640,10 @@ impl App {
632640 } ;
633641 if let Some ( WorkspaceTab :: Editor ( slot) ) = self . workspace_tabs . borrow_mut ( ) . get_mut ( & id) {
634642 slot. page . set_title ( & label) ;
635- slot. page . set_tooltip ( & label) ;
643+ // Pass empty when no extra info to clear any prior tooltip;
644+ // libadwaita treats empty-string as no tooltip.
645+ let tooltip = editor_tab_tooltip ( & query, & label) . unwrap_or_default ( ) ;
646+ slot. page . set_tooltip ( & tooltip) ;
636647 slot. query = query;
637648 }
638649 self . persist_workspace_state ( ) ;
@@ -681,3 +692,31 @@ fn qualified_browse_tab_label(schemas_count: usize, schema: Option<&str>, table:
681692fn default_editor_tab_label ( n : usize ) -> String {
682693 crate :: tr!( "Query {n}" ) . replace ( "{n}" , & n. to_string ( ) )
683694}
695+
696+ /// Returns a tooltip for a Browse tab, but only when it would add info
697+ /// beyond the visible label. When the label is already
698+ /// `schema.table`, or there is no schema, the tooltip would just
699+ /// duplicate the tab title and we skip it.
700+ fn browse_tab_tooltip ( schema : Option < & str > , table : & str , label : & str ) -> Option < String > {
701+ let s = schema?;
702+ let qualified = format ! ( "{s}.{table}" ) ;
703+ if qualified == label { None } else { Some ( qualified) }
704+ }
705+
706+ /// Returns a tooltip for an Editor tab. Empty for blank queries; for
707+ /// non-empty queries, a 200-char preview — but only when distinct from
708+ /// the (truncated) label, so non-truncated labels don't get a redundant
709+ /// hover popup.
710+ fn editor_tab_tooltip ( query : & str , label : & str ) -> Option < String > {
711+ let q = query. trim ( ) ;
712+ if q. is_empty ( ) {
713+ return None ;
714+ }
715+ let preview: String = q. chars ( ) . take ( 200 ) . collect ( ) ;
716+ let preview = if q. chars ( ) . count ( ) > 200 {
717+ format ! ( "{preview}…" )
718+ } else {
719+ preview
720+ } ;
721+ if preview == label { None } else { Some ( preview) }
722+ }
0 commit comments