From 8cf0770d70dfa9dd6727e0e4a9594bd29cbb34b2 Mon Sep 17 00:00:00 2001 From: vesp Date: Sat, 20 Dec 2025 23:43:51 +0100 Subject: [PATCH] Add close tab buttons --- src/window.py | 77 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/src/window.py b/src/window.py index 9f7ee59..4c8a27c 100644 --- a/src/window.py +++ b/src/window.py @@ -205,7 +205,7 @@ class RosterWindow(Adw.ApplicationWindow): # Show tab bar only if we have 2 or more tabs self.tab_bar_container.set_visible(num_tabs >= 2) - # Update tab bar with buttons (simplified - just show count for now) + # Update tab bar with buttons if num_tabs >= 2: # Clear existing children child = self.tab_bar_container.get_first_child() @@ -214,14 +214,64 @@ class RosterWindow(Adw.ApplicationWindow): self.tab_bar_container.remove(child) child = next_child - # Add simple tab buttons + # Add tab buttons with close button for tab in self.tab_manager.tabs: - tab_btn = Gtk.Button(label=tab.name[:20]) # Truncate long names - tab_btn.add_css_class("flat") + # Create a box for tab label + close button + tab_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + + # Tab label button + tab_label_btn = Gtk.Button(label=tab.name[:20]) # Truncate long names + tab_label_btn.add_css_class("flat") if tab.id == self.current_tab_id: - tab_btn.add_css_class("suggested-action") - tab_btn.connect("clicked", lambda btn, tid=tab.id: self._switch_to_tab(tid)) - self.tab_bar_container.append(tab_btn) + tab_label_btn.add_css_class("suggested-action") + tab_label_btn.connect("clicked", lambda btn, tid=tab.id: self._switch_to_tab(tid)) + tab_box.append(tab_label_btn) + + # Close button + close_btn = Gtk.Button() + close_btn.set_icon_name("window-close-symbolic") + close_btn.add_css_class("flat") + close_btn.add_css_class("circular") + close_btn.set_tooltip_text("Close tab") + close_btn.connect("clicked", lambda btn, tid=tab.id: self._close_tab(tid)) + tab_box.append(close_btn) + + self.tab_bar_container.append(tab_box) + + def _close_tab(self, tab_id): + """Close a tab.""" + # Save current tab state before closing + if self.current_tab_id == tab_id: + current_tab = self.tab_manager.get_tab_by_id(self.current_tab_id) + if current_tab: + current_tab.request = self._build_request_from_ui() + + # Close the tab + success = self.tab_manager.close_tab(tab_id) + + if success: + # If we closed the last tab, create a new one + if len(self.tab_manager.tabs) == 0: + self._create_new_tab() + else: + # Switch to the active tab (tab_manager already updated active_tab_id) + active_tab = self.tab_manager.get_active_tab() + if active_tab: + self.current_tab_id = active_tab.id + self._load_request_to_ui(active_tab.request) + if active_tab.response: + self._display_response(active_tab.response) + else: + # Clear response display + self.status_label.set_text("Ready") + self.time_label.set_text("") + buffer = self.response_headers_textview.get_buffer() + buffer.set_text("") + buffer = self.response_body_sourceview.get_buffer() + buffer.set_text("") + + # Update tab bar + self._update_tab_bar_visibility() def _switch_to_tab(self, tab_id): """Switch to a different tab.""" @@ -275,12 +325,23 @@ class RosterWindow(Adw.ApplicationWindow): def _create_actions(self): """Create window-level actions.""" - # New tab shortcut + # New tab shortcut (Ctrl+T) action = Gio.SimpleAction.new("new-tab", None) action.connect("activate", lambda a, p: self._on_new_request_clicked(None)) self.add_action(action) self.get_application().set_accels_for_action("win.new-tab", ["t"]) + # Close tab shortcut (Ctrl+W) + action = Gio.SimpleAction.new("close-tab", None) + action.connect("activate", lambda a, p: self._close_current_tab()) + self.add_action(action) + self.get_application().set_accels_for_action("win.close-tab", ["w"]) + + def _close_current_tab(self): + """Close the currently active tab.""" + if self.current_tab_id: + self._close_tab(self.current_tab_id) + def _setup_method_dropdown(self): """Populate HTTP method dropdown.""" methods = Gtk.StringList()