@@ -1049,32 +1049,25 @@ impl BrowseTab {
10491049 self . suppress_combo_emit . set ( false ) ;
10501050 }
10511051
1052- /// Decide whether the inner stack shows the empty status page or
1053- /// the grid. The empty page only makes sense on the first page
1054- /// with no persisted rows AND no in-memory drafts; any draft (or
1055- /// any persisted row) means the grid has content to show and
1056- /// must take over.
1052+ /// Switch the inner stack to the grid once the first page has
1053+ /// loaded. Previously this helper also flipped to a dedicated
1054+ /// "empty" AdwStatusPage when there were 0 rows + 0 drafts on
1055+ /// page 0 — but that pattern triggered a GtkListBase bounds
1056+ /// invariant violation when the user then inserted a draft and
1057+ /// the stack crossfaded back to "grid": the GtkColumnView's
1058+ /// adjustments hadn't been allocated yet because the view was
1059+ /// the hidden stack child during the empty interlude, and the
1060+ /// first scroll / select call against it aborted with
1061+ /// `gtk_list_base_update_adjustments: bounds.y == 0`.
10571062 ///
1058- /// Called from every code path that mutates either side of the
1059- /// equation: `refresh_grid_chrome` (post `RowsLoaded`),
1060- /// `InsertRow` (after appending the draft), and any future
1061- /// path that adds / removes drafts without going through a
1062- /// fresh page fetch. Going through a single helper keeps the
1063- /// empty ↔ grid transition derivable from observed state
1064- /// rather than ad-hoc flips at each call site.
1063+ /// GNOME Files / Builder don't show a status page for empty
1064+ /// lists either — they just render an empty list with column
1065+ /// headers. Mirror that: once the grid is built, stay on it
1066+ /// regardless of row count. The "Press Ctrl+N to add the first
1067+ /// row" hint moves into the column view's empty body (handled
1068+ /// natively by GtkColumnView's empty-area rendering).
10651069 fn refresh_inner_stack_visibility ( & self ) {
1066- let has_persisted_rows = self
1067- . current_result
1068- . as_ref ( )
1069- . map ( |r| !r. rows . is_empty ( ) )
1070- . unwrap_or ( false ) ;
1071- let has_drafts = crate :: services:: change_tracker:: with_tab_ref ( self . tab_id , |t| !t. drafts ( ) . is_empty ( ) )
1072- . unwrap_or ( false ) ;
1073- let on_first_page = self . current_offset == 0 ;
1074- if !has_persisted_rows && !has_drafts && on_first_page {
1075- self . show_empty_inner ( ) ;
1076- self . inner_stack . set_visible_child_name ( "empty" ) ;
1077- } else {
1070+ if self . current_result . is_some ( ) {
10781071 self . inner_stack . set_visible_child_name ( "grid" ) ;
10791072 }
10801073 }
@@ -1263,34 +1256,6 @@ impl BrowseTab {
12631256 self . replace_status_child ( "error" , & page) ;
12641257 }
12651258
1266- /// Empty-state placeholder for tables with no rows on offset 0 and
1267- /// no pending drafts. AdwStatusPage with a context-appropriate
1268- /// description: "Press Ctrl+N to add the first row" for editable
1269- /// tables, "Use the SQL editor to add rows" for read-only ones.
1270- fn show_empty_inner ( & self ) {
1271- let ( title, description) = if self . read_only {
1272- (
1273- crate :: tr!( "No rows yet" ) ,
1274- crate :: tr!( "This table is empty. Use the SQL editor to add rows." ) ,
1275- )
1276- } else if !self . has_primary_key ( ) {
1277- (
1278- crate :: tr!( "No rows yet" ) ,
1279- crate :: tr!( "This table has no primary key. Use the SQL editor to add rows." ) ,
1280- )
1281- } else {
1282- (
1283- crate :: tr!( "No rows yet" ) ,
1284- crate :: tr!( "Press Ctrl+N to add the first row." ) ,
1285- )
1286- } ;
1287- let page = adw:: StatusPage :: builder ( )
1288- . icon_name ( "view-grid-symbolic" )
1289- . title ( & title)
1290- . description ( & description)
1291- . build ( ) ;
1292- self . replace_status_child ( "empty" , & page) ;
1293- }
12941259}
12951260
12961261impl SimpleComponent for BrowseTab {
0 commit comments