Class: RosettAi::Desktop::Gtk4App

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

Overview

Main GTK4/Adwaita application for rai desktop integration.

SAFETY PRINCIPLES:

  1. All event handlers are wrapped with safe_action() - NEVER crash on user action
  2. D-Bus client is defensive - returns safe defaults, never raises
  3. Widget construction is wrapped - missing features degrade gracefully
  4. Error dialogs inform users instead of crashing

This is a standalone app that communicates with rosett-ai exclusively via D-Bus. It does NOT import Ruby Rosett-AI modules for business logic. All operations go through the DbusClient.

Follows GNOME HIG: single-window, instant-apply preferences, headerbar with title and buttons.

Constant Summary collapse

APPLICATION_ID =
'be.neatnerds.rosettai'
UNAVAILABLE_MESSAGE =
'GTK4 app requires the adwaita gem. Install: gem install adwaita'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGtk4App

Returns a new instance of Gtk4App.



30
31
32
33
34
35
# File 'lib/rosett_ai/desktop/gtk4_app.rb', line 30

def initialize
  @dbus_client = DbusClient.new
  @window = nil
  @application = nil
  @toast_overlay = nil
end

Instance Attribute Details

#applicationObject (readonly)

Returns the value of attribute application.



28
29
30
# File 'lib/rosett_ai/desktop/gtk4_app.rb', line 28

def application
  @application
end

#dbus_clientObject (readonly)

Returns the value of attribute dbus_client.



28
29
30
# File 'lib/rosett_ai/desktop/gtk4_app.rb', line 28

def dbus_client
  @dbus_client
end

Class Method Details

.available?Boolean

Check if GTK4/Adwaita is available.

Returns:

  • (Boolean)


40
41
42
43
44
45
# File 'lib/rosett_ai/desktop/gtk4_app.rb', line 40

def self.available?
  require 'adwaita'
  true
rescue LoadError
  false
end

Instance Method Details

#run(_argv = ARGV) ⇒ Integer

Run the GTK4 application. SAFETY: Wrapped in rescue to show error dialog on startup failure.

Parameters:

  • _argv (Array<String>) (defaults to: ARGV)

    command-line arguments (ignored)

Returns:

  • (Integer)

    exit code



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

def run(_argv = ARGV)
  GuiLogger.info('Application starting', version: safe_version)
  require_adwaita!

  @application = Adw::Application.new(APPLICATION_ID, Gio::ApplicationFlags::FLAGS_NONE)
  setup_actions
  @application.signal_connect('activate') { safe_action(:on_activate) }
  @application.signal_connect('shutdown') { GuiLogger.info('Application shutdown') }
  GuiLogger.info('Application run loop starting')
  @application.run([])
rescue StandardError => e
  # Last resort error handling - show dialog if possible, print to stderr
  show_fatal_error("Application failed to start: #{e.message}")
  1
end