1. Overview
The FirstRunServicesWindow.hpp header defines the FirstRunServicesWindow class, a GTKmm (GTK4) onboarding window displayed during the first execution of BastionGuard.
This component guides users through the initial configuration of background security services, allowing them to enable or disable recommended system and user-level units in a controlled and transparent manner.
Functionally, FirstRunServicesWindow provides:
- First-run onboarding workflow for service configuration
- Interactive selection of security-related background services
- Support for both user and systemd system units
- Preset selection modes (full vs minimal setup)
- Safe application of service states with confirmation
- Deferred display via conditional startup logic
2. Dependencies and Includes
#include <gtkmm.h>
#include <vector>
#include <string>
- gtkmm.h – GTK4 window widgets, layouts, and event handling
- <vector> – container for checkbox widgets
- <string> – service identifiers and descriptive text
3. Class Declaration and Scope
class FirstRunServicesWindow : public Gtk::Window
The class derives from Gtk::Window, providing a dedicated onboarding dialog that can be shown modally or as a top-level window during first application startup.
4. Public Interface
4.1 Constructor
FirstRunServicesWindow();
Initializes the window, builds the user interface, and prepares service state synchronization logic.
4.2 Conditional Display Helper
static void maybe_show();
Determines whether the first-run window should be displayed based on persisted configuration or startup context. This prevents repeated presentation after initial setup.
4.3 Close Interception
bool on_close_request() override;
Intercepts window close events to ensure that configuration is applied or confirmed before termination.
5. Data Structures
5.1 Service Information Structure
struct ServiceInfo {
std::string name;
std::string label;
std::string description;
};
Encapsulates metadata for each configurable service, used to generate UI elements dynamically.
- name – systemd unit name
- label – human-readable service name
- description – explanatory text shown in the UI
6. UI Components
The interface is built dynamically using collections of check buttons and header controls.
std::vector<Gtk::CheckButton*> check_buttons;
std::vector<std::string> service_names;
Gtk::Button* btn_minimize = nullptr;
Gtk::Button* btn_close = nullptr;
- check_buttons – interactive toggles for each service
- service_names – internal identifiers corresponding to each checkbox
- btn_minimize – header control for minimizing the window
- btn_close – header control for closing the window
7. Internal Logic
7.1 UI Construction
void build_headerbar();
void build_ui();
Builds the header bar and main content area, populating service entries and action buttons.
7.2 State Synchronization
void load_current_states();
Queries the system to determine the current enablement status of each service and updates the UI accordingly.
7.3 Preset Selection
void select_all();
void select_minimal();
Applies predefined selection profiles:
- select_all() – enables all available services
- select_minimal() – enables only essential services
7.4 Apply and Exit
void apply_and_close();
Applies selected service states and closes the window. This method coordinates privilege escalation where required.
7.5 Window Controls
void on_minimize_clicked();
void on_close_clicked();
Handle custom header bar button interactions.
8. Service Management Helpers
8.1 User-Level Units
bool is_user_service_enabled(const std::string& service_name);
bool enable_user_service(const std::string& service_name);
bool disable_user_service(const std::string& service_name);
Manage systemd user services under the current account context.
8.2 System-Level Units
bool is_system_service_enabled(const std::string& unit_name);
bool enable_system_service(const std::string& unit_name);
bool disable_system_service(const std::string& unit_name);
Manage system-wide systemd services using privilege escalation mechanisms such as pkexec.
9. Integration with Application Lifecycle
FirstRunServicesWindow is typically invoked during:
- First application startup
- Post-installation configuration
- Major version upgrades requiring new services
10. Settings Storage
Completion state and selected services are persisted by higher-level configuration subsystems to ensure the window is not shown repeatedly.
11. Platform Integration
This component integrates tightly with Linux systemd, relying on both user and system service managers.
systemctl --userfor per-user servicessystemctlwith privilege escalation for system units- PolicyKit (
pkexec) authorization flows
12. Runtime and Security Considerations
- Least privilege: only essential services should be enabled by default.
- User awareness: descriptions should clearly explain the impact of each service.
- Failure handling: partial enablement failures must be detected and reported.
- Idempotency: repeated application of settings should not destabilize service states.
- Rollback: provide recovery mechanisms if misconfiguration disrupts system behavior.
- Audit logging: service changes should be logged for administrative review.