Interfacing Raku to Gnome GTK+

Gnome::Gtk3::Main

Library initialization, main event loop, and events

Description

Before using GTK+, you need to initialize it; initialization connects to the window system display, and parses some standard command line arguments. The gtk_init() macro initializes GTK+. gtk_init() exits the application if errors occur; to avoid this, use gtk_init_check(). gtk_init_check() allows you to recover from a failed GTK+ initialization - you might start up your application in text mode instead.

However, in these Raku Gnome packages, the initialization takes place automatically as soon as possible. It happens when an object is created which has Gnome::GObject::Object as its parent. It calls init_check() to initialize GTK+.

Like all GUI toolkits, GTK+ uses an event-driven programming model. When the user is doing nothing, GTK+ sits in the “main loop” and waits for input. If the user performs some action - say, a mouse click - then the main loop “wakes up” and delivers an event to GTK+. GTK+ forwards the event to one or more widgets.

When widgets receive an event, they frequently emit one or more “signals”. Signals notify your program that “something interesting happened” by invoking functions you’ve connected to the signal with register-signal() defined in Gnome::GObject::Object. Functions connected to a signal are often termed “callbacks” or “signal handlers”.

When your callbacks are invoked, you would typically take some action - for example, when an Open button is clicked you might display a Gnome::Gtk3::FileChooserDialog. After a callback finishes, GTK+ will return to the main loop and await more user input.

Typical MAIN function for simple GTK+ applications

# Set up signal handlers
class SigHandlers {
  …
}

sub MAIN ( … ) {
  my Gnome::Gtk3::Window $top-window .= new;
  $top-window.set-title('My Application Window');

  # Expand $top-window with other GUI elements
  …

  # Register signal handlers
  …

  # Show all of the GUI and start event loop
  $top-window.show-all;
  Gnome::Gtk3::Main.new.main;

  # Event loop finished, exit program
}

Synopsis

Declaration

unit class Gnome::Gtk3::Main;

Example

# Setup user interface
…
# Start main loop
Gnome::Gtk3::Main.new.main;

# Elsewhere in some exit handler
method exit ( ) {
  Gnome::Gtk3::Main.new.quit;
}

Methods

new

Create a GtkMain object.

submethod BUILD ( )

do-event

Processes a single GDK event.

This is public only to allow filtering of events between GDK and GTK+. You will not usually need to call this function directly.

While you should not call this function directly, you might want to know how exactly events are handled. So here is what this function does with the event:

  1. Compress enter/leave notify events. If the event passed build an enter/leave pair together with the next event (peeked from GDK), both events are thrown away. This is to avoid a backlog of (de-)highlighting widgets crossed by the pointer.

  2. Find the widget which got the event. If the widget can’t be determined the event is thrown away unless it belongs to a INCR transaction.

  3. Then the event is pushed onto a stack so you can query the currently handled event with current-event().

  4. The event is sent to a widget. If a grab is active all events for widgets that are not in the contained in the grab widget are sent to the latter with a few exceptions:

  • Deletion and destruction events are still sent to the event widget for obvious reasons.

  • Events which directly relate to the visual representation of the event widget.

  • Leave events are delivered to the event widget if there was an enter event delivered to it before without the paired leave event.

  • Drag events are not redirected because it is unclear what the semantics of that would be.

  1. After finishing the delivery the event is popped from the event stack.

    method do-event ( N-GdkEvent $event )

  • N-GdkEvent $event; An event to process (normally passed by GDK)

check-version

Checks that the GTK+ library in use is compatible with the given version. Generally you would pass in the constants GTK-MAJOR-VERSION, GTK-MINOR-VERSION, GTK-MICRO-VERSION as the three arguments to this function; that produces a check that the library in use is compatible with the version of GTK+ the application or module was compiled against.

Compatibility is defined by two things: first the version of the running library is newer than the version $required-major.required-minor.$required-micro. Second the running library must be binary compatible with the version $required-major.required-minor.$required-micro (same major version.)

This function is primarily for GTK+ modules; the module can call this function to check that it wasn’t loaded into an incompatible version of GTK+. However, such a check isn’t completely reliable, since the module may be linked against an old version of GTK+ and calling the old version of gtk-check-version(), but still get loaded into an application using a newer version of GTK+.

Returns: undefined if the GTK+ library is compatible with the given version, or a string describing the version mismatch. The returned string is owned by GTK+ and should not be modified or freed.

method check-version (
  UInt $required_major, UInt $required_minor,
  UInt $required_micro
  --> Str
)
  • UInt $required_major; the required major version

  • UInt $required_minor; the required minor version

  • UInt $required_micro; the required micro version

device-grab-add

Adds a GTK+ grab on device, so all the events on device and its associated pointer or keyboard (if any) are delivered to widget. If the block-others parameter is True, any other devices will be unable to interact with widget during the grab.

method device-grab-add (
  N-GObject $widget, N-GObject $device, Bool $block_others
)
  • N-GObject $widget; a Gnome::Gtk3::Widget

  • N-GObject $device; a Gnome::Gdk3::Device to grab on.

  • Int $block_others; True to prevent other devices to interact with widget.

device-grab-remove

Removes a device grab from the given widget.

You have to pair calls to device-grab-add() and device-grab-remove().

method device-grab-remove ( N-GObject $widget, N-GObject $device )
  • N-GObject $widget; a Gnome::Gtk3::Widget

  • N-GObject $device; a Gnome::Gdk3::Device

disable-setlocale

Prevents init(), init-check(), init-with-args() and parse-args() from automatically calling setlocale (LC-ALL, ""). You would want to use this function if you wanted to set the locale for your program to something other than the user’s locale, or if you wanted to set different values for different locale categories.

Most programs should not need to call this function.

method disable-setlocale ( )

events-pending

Checks if any events are pending.

This can be used to update the UI and invoke timeouts etc. while doing some time intensive computation.

Example updating the UI during a long computation

# computation going on …

while ( $main.events-pending ) {
  $main.iteration;
}

# … computation continued

Returns: True if any events are pending, False otherwise

method events-pending ( --> Bool )

get-current-event

Obtains a copy of the event currently being processed by GTK+.

For example, if you are handling a clicked signal, the current event will be the Gnome::Gdk3::EventButton that triggered the clicked signal.

Returns: a copy of the current event, or undefined if there is no current event.

method get-current-event ( --> N-GdkEvent )

get-current-event-device

If there is a current event and it has a device, return that device, otherwise return an invalid object.

method get-current-event-device ( --> Gnome::Gdk3::Device )

get-current-event-state

If there is a current event and it has a state field, place that state field in state and return True, otherwise return False.

Returns: True if there was a current event and it had a state field

method get-current-event-state ( GdkModifierType $state --> Bool )
  • GdkModifierType $state; (out): a location to store the state of the current event

get-current-event-time

If there is a current event and it has a timestamp, return that timestamp, otherwise return GDK-CURRENT-TIME.

method get-current-event-time ( --> UInt )

get-event-widget

If $event is undefined or the event was not associated with any widget, returns an invalid object, otherwise returns the widget that received the event originally.

Returns: the widget that originally received $event

method get-event-widget ( N-GdkEvent $event --> Gnome::Gdk3::Events )
  • N-GdkEvent $event; a Gnome::Gdk3::Events

get-locale-direction

Get the direction of the current locale. This is the expected reading direction for text and UI.

This function depends on the current locale being set with setlocale() and will default to setting the GTK-TEXT-DIR-LTR direction otherwise. GTK-TEXT-DIR-NONE will never be returned.

GTK+ sets the default text direction according to the locale during init(), and you should normally use Gnome::Gtk3::Widget.get-direction() or Gnome::Gtk3::Widget.get-default-direction() to obtain the current direcion.

This function is only needed in rare cases when the locale is changed after GTK+ has already been initialized. In this case, you can use it to update the default text direction as follows:

Returns: the Gnome::Gtk3::TextDirection of the current locale

method get-locale-direction ( --> GtkTextDirection )

grab-add

Makes $widget the current grabbed widget.

This means that interaction with other widgets in the same application is blocked and mouse as well as keyboard events are delivered to this widget.

If $widget is not sensitive, it is not set as the current grabbed widget and this function does nothing.

method grab-add ( N-GObject $widget )
  • N-GObject $widget; The widget that grabs keyboard and pointer events

grab-get-current

Queries the current grab of the default window group.

Returns: The widget which currently has the grab or undefined if no grab is active

method grab-get-current ( --> N-GObject )

grab-remove

Removes the grab from the given widget.

You have to pair calls to grab-add() and grab-remove().

If $widget does not have the grab, this function does nothing.

method grab-remove ( N-GObject $widget )
  • N-GObject $widget; The widget which gives up the grab

init

Call this function before using any other GTK+ functions in your GUI applications. It will initialize everything needed to operate the toolkit and parses some standard command line options.

There are no arguments to this function because Raku has its commandline arguments in @*ARGS. That array will be adjusted after this call if needed.

Note that initialization, using init-check(), takes place automatically when Gnome::GObject::Object is initialized. That class is inherited by almost all classes.

This function will terminate your program if it was unable to initialize the windowing system for some reason. If you want your program to fall back to a textual interface you want to call init-check() instead.

method init ( )

init-check

This function does the same work as init() with only a single change: It does not terminate the program if the commandline arguments couldn’t be parsed or the windowing system can’t be initialized. Instead it returns False on failure.

This way the application can fall back to some other means of communication with the user - for example a curses or command line interface.

Returns: True if the commandline arguments (if any) were valid and the windowing system has been successfully initialized, False otherwise.

method init-check ( --> Bool )

main

Runs the main loop until quit() is called.

You can nest calls to main(). In that case quit() will make the innermost invocation of the main loop return.

method main ( )

propagate-event

Sends an event to a widget, propagating the event to parent widgets if the event remains unhandled.

Events received by GTK+ from GDK normally begin in do-event(). Depending on the type of event, existence of modal dialogs, grabs, etc., the event may be propagated; if so, this function is used.

propagate-event() calls Gnome::Gtk3::Widget.event() on each widget it decides to send the event to. So widget-event() is the lowest-level function; it simply emits the event and possibly an event-specific signal on a widget. propagate-event() is a bit higher-level, and main-do-event() is the highest level.

All that said, you most likely don’t want to use any of these functions; synthesizing events is rarely needed. There are almost certainly better ways to achieve your goals. For example, use Gnome::Gdk3::Window.invalidate-rect() or Gnome::Gtk3::Widget.queue-draw() instead of making up expose events.

method propagate-event ( N-GObject $widget, N-GdkEvent $event )
  • N-GObject $widget; a Gnome::Gtk3::Widget

  • N-GdkEvent $event; an event

iteration

Runs a single iteration of the mainloop.

If no events are waiting to be processed GTK+ will block until the next event is noticed. If you don’t want to block look at iteration-do() or check if any events are pending with events-pending() first.

Returns: True if quit() has been called for the innermost mainloop

method iteration ( --> Bool )

iteration-do

Runs a single iteration of the mainloop. If no events are available either return or block depending on the value of blocking.

Returns: True if quit() has been called for the innermost mainloop

method iteration-do ( Int $blocking --> Bool )
  • Int $blocking; True if you want GTK+ to block if no events are pending

level

Asks for the current nesting level of the main loop.

Returns: the nesting level of the current invocation of the main loop

method level ( --> UInt )

quit

Makes the innermost invocation of the main loop return when it regains control.

method quit ( )