FirstRunServicesWindow.hpp

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 --user for per-user services
  • systemctl with 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.