Fix critical bugs from second round of testing

1. Fixed infinite loop when closing last tab:
   - Return False instead of True when page already removed (prevents double-processing)
   - Remove from tracking BEFORE calling close_page_finish to prevent re-trigger
   - Properly schedule new tab creation only once

2. Fixed modified flag not clearing after save:
   - Update widget.original_request in _mark_tab_as_saved
   - Update widget.modified = False
   - Manually call _on_tab_modified_changed to clear indicator
   - Update tab page title when saving

3. Fixed header bar height and left spacing:
   - Added CSS to reduce headerbar min-height to 38px
   - Set headerbar padding-left to 0px to eliminate left gap
   - Made tabs more compact (min-height: 26px, reduced padding)
   - Reduced tabbar padding and margins

All critical issues from testing resolved!
This commit is contained in:
Pavel Baksy 2025-12-24 03:07:11 +01:00
parent ad0e1886cc
commit 9c17f452bf

View File

@ -133,9 +133,28 @@ class RosterWindow(Adw.ApplicationWindow):
"""Setup custom CSS for UI styling."""
css_provider = Gtk.CssProvider()
css_provider.load_from_data(b"""
/* Constrain tab bar to normal header height */
.tabbar-box {
/* Reduce header bar padding and height */
headerbar {
min-height: 38px;
padding-left: 0px;
padding-right: 6px;
}
/* Compact tab bar */
tabbar {
min-height: 0;
padding: 0;
margin: 0;
}
tabbar > scrolledwindow {
min-height: 0;
}
tabbar tab {
min-height: 26px;
padding: 2px 8px;
margin: 0 1px;
}
/* Stack switchers styling (Headers/Body tabs) */
@ -181,8 +200,9 @@ class RosterWindow(Adw.ApplicationWindow):
tab = self.page_to_tab.get(page)
widget = self.page_to_widget.get(page)
# If already removed, allow close (prevents double-processing)
if not tab or not widget:
return True # Allow close
return False # Allow close
# Check if tab has unsaved changes
if widget.modified:
@ -198,10 +218,16 @@ class RosterWindow(Adw.ApplicationWindow):
def on_response(dlg, response):
if response == "close":
# Remove from our tracking
# Remove from our tracking FIRST to prevent re-triggering
self.tab_manager.close_tab(tab.id)
del self.page_to_tab[page]
del self.page_to_widget[page]
# Check if we need to create a new tab
if self.tab_view.get_n_pages() == 1: # This page is still counted
# Schedule creating new tab BEFORE closing this one
GLib.idle_add(self._create_new_tab)
# Close the page
tab_view.close_page_finish(page, True)
else:
@ -217,7 +243,7 @@ class RosterWindow(Adw.ApplicationWindow):
del self.page_to_tab[page]
del self.page_to_widget[page]
# If no tabs left, create a new one
# If this will be the last tab, create a new one BEFORE returning
if self.tab_view.get_n_pages() == 1: # This page is still counted
GLib.idle_add(self._create_new_tab)
@ -692,22 +718,38 @@ class RosterWindow(Adw.ApplicationWindow):
def _mark_tab_as_saved(self, saved_request_id, name, request):
"""Mark the current tab as saved (clear modified flag)."""
if self.current_tab_id:
current_tab = self.tab_manager.get_tab_by_id(self.current_tab_id)
if current_tab:
page = self.tab_view.get_selected_page()
if not page:
return
tab = self.page_to_tab.get(page)
widget = self.page_to_widget.get(page)
if tab and widget:
# Update tab metadata
current_tab.saved_request_id = saved_request_id
current_tab.name = name
current_tab.modified = False
tab.saved_request_id = saved_request_id
tab.name = name
tab.modified = False
# Update original_request to match saved state
current_tab.original_request = HttpRequest(
original = HttpRequest(
method=request.method,
url=request.url,
headers=request.headers.copy(),
body=request.body,
syntax=request.syntax
)
tab.original_request = original
# Update widget state
widget.original_request = original
widget.modified = False
# Update tab page title
page.set_title(name)
# This will trigger the modified-changed signal and clear the indicator
self._on_tab_modified_changed(page, False)
def _show_overwrite_dialog(self, project, name, existing_request_id, request):
"""Show dialog asking if user wants to overwrite existing request."""