Class: RosettAi::Desktop::Gtk4Preferences

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/desktop/gtk4_preferences.rb

Overview

Preferences dialog for GTK4 app using AdwPreferencesDialog.

SAFETY PRINCIPLES:

  1. All callbacks are wrapped with safe_callback() - NEVER crash on user action
  2. D-Bus client operations are defensive - always handle failures gracefully
  3. Missing libadwaita features degrade gracefully
  4. All status queries have rescue blocks

Follows GNOME HIG instant-apply pattern - changes are applied immediately via D-Bus, no OK/Apply buttons.

Constant Summary collapse

FALLBACK_ENGINES =
[
  { name: 'claude', display_name: 'Claude' },
  { name: 'generic', display_name: 'Generic' },
  { name: 'agents_md', display_name: 'AGENTS.md' }
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(parent_window, dbus_client) ⇒ Gtk4Preferences

Returns a new instance of Gtk4Preferences.



21
22
23
24
25
# File 'lib/rosett_ai/desktop/gtk4_preferences.rb', line 21

def initialize(parent_window, dbus_client)
  @parent = parent_window
  @dbus_client = dbus_client
  @dialog = nil
end

Instance Method Details

#buildAdw::PreferencesDialog?

Build and return the preferences dialog. SAFETY: Returns nil on failure instead of raising.

Returns:

  • (Adw::PreferencesDialog, nil)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rosett_ai/desktop/gtk4_preferences.rb', line 31

def build
  require 'adwaita'
  Object.const_set(:Adw, Adwaita) unless Object.const_defined?(:Adw)

  # Try PreferencesDialog first (libadwaita 1.4+), fall back to PreferencesWindow
  @dialog = create_preferences_dialog
  return nil unless @dialog

  safe_add_page(:add_general_page)
  safe_add_page(:add_context_page)
  safe_add_page(:add_advanced_page)

  @dialog
rescue StandardError => e
  log_error('Failed to build preferences dialog', e)
  nil
end

#presentObject

Present the preferences dialog. SAFETY: Silently fails if dialog cannot be built.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rosett_ai/desktop/gtk4_preferences.rb', line 51

def present
  GuiLogger.action(:present_preferences) do
    build unless @dialog
    return unless @dialog

    # PreferencesDialog (1.4+) uses present(parent), PreferencesWindow (1.0+) uses present()
    # Use defined? check since PreferencesDialog may not exist in older libadwaita
    if defined?(Adw::PreferencesDialog) && @dialog.is_a?(Adw::PreferencesDialog)
      @dialog.present(@parent)
    else
      @dialog.transient_for = @parent if @dialog.respond_to?(:transient_for=)
      @dialog.present
    end
  end
rescue StandardError => e
  log_error('Failed to present preferences dialog', e)
end