### GTK UI Definition File Example Source: https://developer.gnome.org/documentation/tutorials/widget-templates An example of an XML file defining a GTK widget's UI structure, including child widgets like an entry and a button. This file is typically bundled with the application using GResource. ```xml ``` -------------------------------- ### C: Initiate Asynchronous Connection and Read Source: https://developer.gnome.org/documentation/tutorials/asynchronous-programming Initiates an asynchronous connection to a server and then starts an asynchronous read operation in C using gio library. It uses G_PRIORITY_DEFAULT for the read operation and a cancellable object for managing the connection process. Errors during connection setup are handled. ```c /* any time. The buffer could instead be allocated dynamically if this is a * problem. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (connection)); g_input_stream_read_async (input_stream, priv->message_buffer, sizeof (priv->message_buffer), G_PRIORITY_DEFAULT, priv->connect_cancellable, connect_to_server_cb3, self); done: if (error != NULL) { /* Stop the operation. */ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_warning ("Failed to connect to server: %s", error->message); } g_clear_object (&priv->connect_cancellable); g_clear_object (&priv->connection); g_error_free (error); } g_clear_object (&connection); ``` -------------------------------- ### Basic GLib Object Initialization in Python Source: https://developer.gnome.org/documentation/tutorials/asynchronous-programming Demonstrates the basic import and usage of GObject from the gi.repository in Python. This snippet is typically the starting point for any application using GLib's object system in Python, enabling object-oriented programming patterns. ```python import logging from gi.repository import GObject ``` -------------------------------- ### GLib/GTK Floating References Example (C) Source: https://developer.gnome.org/documentation/guidelines/programming/memory-management Demonstrates the usage of floating references in GTK to simplify widget creation and addition to containers. Without floating references, explicit unreferencing is required, leading to more verbose code. The example highlights the conciseness achieved by directly adding newly created widgets to a container, relying on g_object_ref_sink() to manage the reference count. ```c // Without floating references GtkWidget *new_widget; new_widget = gtk_some_widget_new (); gtk_container_add (some_container, new_widget); g_object_unref (new_widget); // With floating references gtk_container_add (some_container, gtk_some_widget_new ()); ``` -------------------------------- ### Create and Configure GtkMenuButton Source: https://developer.gnome.org/documentation/tutorials/beginners/components/menu_button Demonstrates creating a GtkMenuButton, setting its icon, and associating a menu model. The 'menu' variable is assumed to be defined elsewhere. These examples cover C, Vala, JavaScript, and XML implementations. ```c GtkWidget *button = gtk_menu_button_new (); gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (button), "open-menu-symbolic"); // "menu" is defined elsewhere gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu); ``` ```vala // "menu" is defined elsewhere button = Gtk.MenuButton(icon_name="open-menu-symbolic", menu_model=menu) ``` ```javascript // "menu" is defined elsewhere var button = new Gtk.MenuButton () { icon_name = "open-menu-symbolic", menu_model = menu }; ``` ```javascript // "menu" is defined elsewhere const button = new Gtk.MenuButton({ icon_name: "open-menu-symbolic", menu_model: menu, }); ``` ```xml open-menu-symbolic primary_menu_model ``` -------------------------------- ### Create Basic GtkLabel Widget Source: https://developer.gnome.org/documentation/tutorials/beginners/components/label Provides examples of creating a basic GtkLabel widget and adding it to a GtkBox container. This serves as a foundation for more complex label configurations. ```C // Add a switch to enable a feature GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); GtkWidget *sw = gtk_switch_new (); GtkWidget *label = gtk_label_new ("Enable feature");gtk_box_append (GTK_BOX (box), label);gtk_box_append (GTK_BOX (box), sw); ``` ```Vala # Add a switch to enable a feature box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12) switch = Gtk.Switch() label = Gtk.Label(text="Enable feature") box.append(label) box.append(switch) ``` ```JavaScript var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12); var switch = new Gtk.Switch (); var label = new Gtk.Label ("Enable feature"); box.append (label); box.append (switch); ``` ```JavaScript (ES6) // Add a switch to enable a feature const box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, spacing: 12, }); const sw = new Gtk.Switch(); const label = new Gtk.Label({ label: "Enable feature", }); box.append(label); box.append(sw); ``` -------------------------------- ### Bind Window State Properties using Vala (GSettings) Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/saving_state This Vala code example shows the initialization of an Adw.ApplicationWindow and the binding of GSettings keys to window properties. It ensures that 'window-width', 'window-height', and 'window-maximized' are persisted across application sessions. ```vala namespace TextViewer { public class Window : Adw.ApplicationWindow { // ... public Window (Gtk.Application app) { Object (application: app); } construct { var open_action = new SimpleAction ("open", null); open_action.activate.connect (this.open_file_dialog); this.add_action (open_action); var save_action = new SimpleAction ("save-as", null); save_action.activate.connect (this.save_file_dialog); self.add_action (save_action); Gtk.TextBuffer buffer = this.text_view.buffer; buffer.notify["cursor-position"].connect (this.update_cursor_position); this.settings.bind ("window-width", this, "default-width", SettingsBindFlags.DEFAULT); this.settings.bind ("window-height", this, "default-height", SettingsBindFlags.DEFAULT); this.settings.bind ("window-maximized", this, "maximized", SettingsBindFlags.DEFAULT); } } } ``` -------------------------------- ### Initiate Asynchronous File Read (CPython, Vala, JavaScript) Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/opening_files Starts the asynchronous operation to read the contents of a file. This function is non-blocking and uses a callback mechanism to handle completion. Dependencies include Gio library for file operations. ```c static void open_file (TextViewerWindow *self, GFile *file) { g_file_load_contents_async (file, NULL, (GAsyncReadyCallback) open_file_complete, self); } ``` ```python def open_file(self, file): file.load_contents_async(None, self.open_file_complete) ``` ```vala private void open_file (File file) { file.load_contents_async.begin (null, (object, result) => {}); } ``` -------------------------------- ### Asynchronous Server Connection with Gio and GLib Source: https://developer.gnome.org/documentation/tutorials/asynchronous-programming Initiates an asynchronous connection to a server using Gio.Task for managing the operation. It handles setup, address parsing, socket connection, and message reading, with robust error handling and support for cancellation. Dependencies include gi.repository.GLib and gi.repository.Gio. ```Python from gi.repository import GLib from gi.repository import Gio from dataclasses import dataclass @dataclass class ConnectToServerData: connection: Gio.SocketConnection = None message_buffer: list = None class MyObject(GObject.Object): connect_task = None def connect_to_server_async(self, cancellable, callback, user_data): if self.connect_task is not None: error = GLib.Error("Already connecting to the server.", Gio.io_error_quark(), Gio.IOErrorEnum.PENDING) Gio.Task.report_error(self, callback, user_data, None, error) return cancellable = cancellable or Gio.Cancellable() original_callback = callback def callback(source_object, result, not_user_data): original_callback(source_object, result, user_data) task = Gio.Task.new(self, cancellable, callback, user_data) task.set_check_cancellable(False) task.task_data = ConnectToServerData() self.connect_task = task address_file = build_address_file() address_file.load_contents_async(cancellable, connect_to_server_cb1, task) def connect_to_server_cb1(self, address_file, result, task): try: address, etags = address_file.load_contents_finish(result) try: inet_address = Gio.InetAddress.new_from_string(address) except TypeError: raise GLib.Error("Invalid address ‘%s’." % address, Gio.io_error_quark(), Gio.IOErrorEnum.INVALID_ARGUMENT) except GLib.Error as err: self.connect_task = None task.return_error(err) return port = 123 inet_socket_address = Gio.InetSocketAddress.new(inet_address, port) socket_client = Gio.SocketClient() socket_client.connect_async(inet_socket_address, task.get_cancellable(), connect_to_server_cb2, task) def connect_to_server_cb2(self, socket_client, result, task): data = task.task_data try: connection = socket_client.connect_finish(result) except GLib.Error as err: self.connect_task = None task.return_error(err) return data.connection = connection input_stream = connection.get_input_stream() data.message_buffer = input_stream.read_async(GLib.PRIORITY_DEFAULT, task.get_cancellable(), connect_to_server_cb3, task) def connect_to_server_cb3(self, input_stream, result, task): data = task.task_data try: length = input_stream.read_finish(result) assert 0 <= length <= len(data.message_buffer) self.handle_received_message(data.message_buffer, length) task.return_boolean(True) except GLib.Error as err: self.connect_task = None task.return_error(err) def connect_to_server_finish(self, result): if not Gio.Task.is_valid(result, self): return False ``` -------------------------------- ### Create GNOME Application Window (C) Source: https://developer.gnome.org/documentation/tutorials/beginners/components/window This C code demonstrates how to create a minimal GNOME application with a window and a title using the Adwaita library. It initializes the application, defines an activate function to create and present the window, and runs the application. Dependencies include adwaita and gtk. ```c #include G_DECLARE_FINAL_TYPE (MyApplication, my_application, MY, APPLICATION, AdwApplication) struct _MyApplication { AdwApplication parent_instance; }; G_DEFINE_TYPE (MyApplication, my_application, ADW_TYPE_APPLICATION) static void my_application_activate (GApplication *application) { // create a Gtk Window belonging to the application itself GtkWidget *window = gtk_application_window_new (GTK_APPLICATION (application)); gtk_window_set_title (GTK_WINDOW (window), "Welcome to GNOME"); gtk_window_present (GTK_WINDOW (window)); } static void my_application_class_init (MyApplicationClass *klass) { G_APPLICATION_CLASS (klass)->activate = my_application_activate; } static void my_application_init (MyApplication *self) { } int main (int argc, char *argv[]) { GApplication *app = g_object_new (my_application_get_type (), "application-id", "com.example.Application", NULL); return g_application_run (app, argc, argv); } ``` -------------------------------- ### Initialize GSettings in C for TextViewerWindow Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/saving_state Demonstrates how to initialize a GSettings instance for the 'com.example.TextViewer' schema within the TextViewerWindow initialization function in C. This involves creating the GSettings object and assigning it to the 'settings' member of the TextViewerWindow structure. ```c static void text_viewer_window_init (TextViewerWindow *self) { gtk_widget_init_template (GTK_WIDGET (self)); g_autoptr (GSimpleAction) open_action = g_simple_action_new ("open", NULL); g_signal_connect (open_action, "activate", G_CALLBACK (text_viewer_window__open_file_dialog), self); g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (open_action)); g_autoptr (GSimpleAction) save_action = g_simple_action_new ("save-as", NULL); g_signal_connect (save_action, "activate", G_CALLBACK (text_viewer_window__save_file_dialog), self); g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (save_action)); GtkTextBuffer *buffer = gtk_text_view_get_buffer (self->main_text_view); g_signal_connect (buffer, "notify::cursor-position", G_CALLBACK (text_viewer_window__update_cursor_position), self); self->settings = g_settings_new ("com.example.TextViewer"); } ``` -------------------------------- ### Start and Stop Spinner - CPython Source: https://developer.gnome.org/documentation/tutorials/beginners/components/spinner Demonstrates how to create, start, and stop a GtkSpinner widget in CPython. The spinner is automatically stopped after 5 seconds using a timeout function. It relies on the GTK library. ```c static gboolean stop_spinner (gpointer data) { GtkSpinner *spinner = data; gtk_spinner_stop (spinner); return G_SOURCE_REMOVE; } GtkWidget *spinner = gtk_spinner_new (); gtk_spinner_start (GTK_SPINNER (spinner)); // Stop spinner after 5 seconds g_timeout_add_seconds (5, stop_spinner, spinner); ``` ```python spinner = Gtk.Spinner() spinner.start() def stop_spinner(spinner): spinner.stop() return GLib.SOURCE_REMOVE GLib.timeout_add_seconds(5, stop_spinner, spinner) ``` ```javascript var spinner = new Gtk.Spinner (); spinner.start (); // Stop spinner after 5 seconds Timeout.add_seconds (5, () => { spinner.stop (); return Source.REMOVE; }); ``` ```javascript const spinner = new Gtk.Spinner(); spinner.start(); // Stop spinner after 5 seconds GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5, () => { spinner.stop(); return GLib.SOURCE_REMOVE; }); ``` -------------------------------- ### Add Actions to GtkApplicationWindow (CPython, Vala, JavaScript) Source: https://developer.gnome.org/documentation/tutorials/actions Demonstrates how to add a 'save' action to a GtkApplicationWindow and connect it to a button. This involves creating a SimpleAction, connecting its 'activate' signal, and adding it to the window's action map. The button is then configured to trigger this action. This pattern is common for user-initiated commands. ```c static void on_save_activate (GAction *action, GVariant *param) { g_print ("You are welcome"); } static void on_app_activate (GApplication *app) { GtkWidget *window = gtk_application_window_new (GTK_APPLICATION (app)); gtk_window_present (GTK_WINDOW (window)); GAction *action = g_simple_action_new ("save", NULL); g_signal_connect (action, "activate", G_CALLBACK (on_save_activate), NULL); g_action_map_add_action (G_ACTION_MAP (window), action); GtkWidget *button = gtk_button_new_with_label ("Save"); gtk_window_set_child (GTK_WINDOW (window), button); gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.save"); } // ... int main (int argc, char *argv[]) { GtkApplication *app = gtk_application_new ("com.example.App", G_APPLICATION_FLAGS_NONE); g_signal_connect (app, "activate", G_CALLBACK (on_app_activate), NULL); return g_application_run (G_APPLICATION (app), argc, argv); } ``` ```python from gi.repository import Gio, Gtk def on_save_activate(action, _): print "You are welcome" def on_app_activate(app): window = Gtk.ApplicationWindow(application=app) window.present() action = Gio.SimpleAction(name="save") action.connect("activate", on_save_activate) window.add_action(action) button = Gtk.Button(label="Save") window.set_child(button) button.set_action_name("win.save") app = Gtk.Application() app.connect("activate", on_app_activate) app.run([]) ``` ```vala public class Example.App : Gtk.Application { public App () { Object (application_id: "com.example.App", flags: ApplicationFlags.FLAGS_NONE); } public override void activate () { var window = new Gtk.ApplicationWindow (this); window.present (); var action = new SimpleAction ("save", null); action.activate.connect (() => { stdout.printf ("You are welcome\n"); }); window.add_action (action); var button = new Gtk.Button ("Save"); window.child = button; button.action_name = "win.save"; } public static int main (string[] args) { var app = new Example.App (); return app.run (args); } } ``` ```javascript import Gtk from "gi://Gtk?version=4.0"; import Adw from "gi://Adw?version=1"; import Gio from "gi://Gio"; function on_save_activate(action, param) { log("You are welcome"); } function on_app_activate(app) { const window = new Gtk.ApplicationWindow({ application }); window.present(); const action = new Gio.SimpleAction({ name: "save" }); action.connect("activate", on_save_activate); window.add_action(action); const button = new Gtk.Button({ label: "Save" }); window.set_child(button); button.set_action_name("win.save"); } const application = new Gtk.Application(); application.connect("activate", on_app_activate); application.run([]); ``` -------------------------------- ### Add Open Action and Shortcut in Vala Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/opening_files This Vala snippet illustrates adding the 'open' action to TextViewer.Window. It includes creating a SimpleAction within a construct block and connecting its activation to a handler. The 'Ctrl+O' accelerator is then configured for the 'win.open' action in the application's initialization. ```vala namespace TextViewer { [GtkTemplate (ui = "/org/example/app/window.ui")] public class Window : Gtk.ApplicationWindow { [GtkChild] private unowned Gtk.TextView main_text_view; [GtkChild] private unowned Gtk.Button open_button; public Window (Gtk.Application app) { Object (application: app); } construct { var open_action = new SimpleAction ("open", null); open_action.activate.connect (this.open_file_dialog); this.add_action (open_action); } } } public Application () { Object (application_id: "com.example.TextViewer", flags: ApplicationFlags.FLAGS_NONE); } construct { // ... this.set_accels_for_action ("win.open", { "o" }); } ``` -------------------------------- ### C Compiler Deprecation Warning Example Source: https://developer.gnome.org/documentation/tutorials/deprecations Shows an example of a C compiler warning generated when a deprecated function is used during compilation. This warning helps developers identify and address the use of outdated APIs. ```c $ make testheaderbar CC testheaderbar.o testheaderbar.c: In function ‘main’: testheaderbar.c:192:3: warning: ‘gtk_window_reshow_with_initial_size’ is deprecated (declared at ../gtk/gtkwindow.h:419) [-Wdeprecated-declarations] gtk_window_reshow_with_initial_size (GTK_WINDOW (window)); ^ CCLD testheaderbar ``` -------------------------------- ### Install Icons Using Meson Build System Source: https://developer.gnome.org/documentation/tutorials/themed-icons Demonstrates how to install application icons to the correct directories within the system's icon theme structure using the Meson build system. This ensures that icons are discoverable by the GtkIconTheme. ```meson # Define PKG_DATADIR as a global symbol pkg_datadir = get_option('prefix') / get_option('datadir') / meson.project_name() add_project_arguments('-DPKG_DATADIR=@0@'.format(datadir), language: 'c') # List the icons to install action_icons_dir = pkg_datadir / 'icons/hicolor/16x16/actions' action_icons = [ 'action-name-1.png', 'action-name-2.png', ] # Install the icons install_data(action_icons, install_dir: action_icons_dir) ``` -------------------------------- ### Initialize GSettings in Python for TextViewerWindow Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/saving_state Illustrates how to initialize a GSettings instance for the 'com.example.TextViewer' schema in the `__init__` method of the TextViewerWindow class using Python. This makes the settings accessible for the lifetime of the window object. ```python def __init__(self, **kwargs): super().__init__(**kwargs) open_action = Gio.SimpleAction(name="open") open_action.connect("activate", self.open_file_dialog) self.add_action(open_action) save_action = Gio.SimpleAction(name="save-as") save_action.connect("activate", self.save_file_dialog) self.add_action(save_action) buffer = self.main_text_view.get_buffer() buffer.connect("notify::cursor-position", self.update_cursor_position) self.settings = Gio.Settings(schema_id="com.example.TextViewer") ``` -------------------------------- ### Original UI Definition (XML) Source: https://developer.gnome.org/documentation/tutorials/widget-templates This snippet shows an example of a complex UI definition with nested widgets, illustrating the need for templates to improve maintainability. ```xml vertical ``` -------------------------------- ### CPython: Async Server Connection with GTask Source: https://developer.gnome.org/documentation/tutorials/asynchronous-programming This CPython example demonstrates initiating an asynchronous server connection using GTask. It sets up task data for connection state, handles cancellation, and initiates the first step of loading the address file. The function uses GTask to manage the overall asynchronous operation and its associated state. ```c static void connect_to_server_cb1 (GObject *source_object, GAsyncResult *result, gpointer user_data); static void connect_to_server_cb2 (GObject *source_object, GAsyncResult *result, gpointer user_data); static void connect_to_server_cb3 (GObject *source_object, GAsyncResult *result, gpointer user_data); typedef struct { GSocketConnection *connection; /* nullable; owned */ guint8 message_buffer[128]; } ConnectToServerData; static void connect_to_server_data_free (ConnectToServerData *data) { g_clear_object (&data->connection); } void my_object_connect_to_server_async (MyObject *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { MyObjectPrivate *priv; GTask *task = NULL; /* owned */ ConnectToServerData *data = NULL; /* owned */ GFile *address_file = NULL; /* owned */ g_return_if_fail (MY_IS_OBJECT (self)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); priv = my_object_get_instance_private (self); if (priv->connect_task != NULL) { g_task_report_new_error (self, callback, user_data, NULL, G_IO_ERROR, G_IO_ERROR_PENDING, "Already connecting to the server."); return; } /* Set up a cancellable. */ if (cancellable != NULL) { g_object_ref (cancellable); } else { cancellable = g_cancellable_new (); } /* Set up the task. */ task = g_task_new (self, cancellable, callback, user_data); g_task_set_check_cancellable (task, FALSE); data = g_malloc0 (sizeof (ConnectToServerData)); g_task_set_task_data (task, data, (GDestroyNotify) connect_to_server_data_free); g_object_unref (cancellable); priv->connect_task = g_object_ref (task); /* Read the socket address. */ address_file = build_address_file (); g_file_load_contents_async (address_file, g_task_get_cancellable (task), connect_to_server_cb1, g_object_ref (task)); g_object_unref (address_file); g_clear_object (&task); } static void connect_to_server_cb1 (GObject *source_object, GAsyncResult *result, gpointer user_data) { MyObject *self; MyObjectPrivate *priv; GTask *task = NULL; /* owned */ GFile *address_file; /* unowned */ gchar *address = NULL; /* owned */ gsize address_size = 0; GInetAddress *inet_address = NULL; /* owned */ GInetSocketAddress *inet_socket_address = NULL; /* owned */ guint16 port = 123; GSocketClient *socket_client = NULL; /* owned */ GError *error = NULL; address_file = G_FILE (source_object); task = G_TASK (user_data); self = g_task_get_source_object (task); priv = my_object_get_instance_private (self); /* Finish loading the address. */ g_file_load_contents_finish (address_file, result, &address, &address_size, NULL, &error); if (error != NULL) { goto done; } /* Parse the address. */ inet_address = g_inet_address_new_from_string (address); if (inet_address == NULL) { ``` -------------------------------- ### Open File Dialog in CPython, Vala, and JavaScript Source: https://developer.gnome.org/documentation/tutorials/beginners/components/file_dialog Demonstrates how to implement the native file selection dialog for opening files. It covers setting up the dialog, handling user responses, and retrieving the selected file. This method is preferred for sandboxed environments. Note that native dialogs are not widgets and require manual lifetime management. ```python self._native = Gtk.FileChooserNative( title="Open File", # "self.main_window" is defined elsewhere as a Gtk.Window transient_for=self.main_window, action=Gtk.FileChooserAction.OPEN, accept_label="_Open", cancel_label="_Cancel", ) def on_file_open_response(native, response): if response == Gtk.ResponseType.ACCEPT: self.open_file(native.get_file()) self._native = None self._native.connect("response", on_file_open_response) self._native.show() ``` ```javascript var native = new Gtk.FileChooserNative ("Open File", parent_window, Gtk.FileChooserAction.OPEN, "_Open", "_Cancel"); native.response.connect ((response_id) => { if (response_id == Gtk.ResponseType.ACCEPT) open_file (native.get_file ()); native = null; }; native.show (); ``` ```javascript const native = new Gtk.FileChooserNative({ title: "Open File", transient_for: parent_window, action: Gtk.FileChooserAction.OPEN, accept_label: "_Open", cancel_label: "_Cancel", }); native.connect("response", (self, response_id) => { if (response_id === Gtk.ResponseType.ACCEPT) { open_file(native.get_file()); } }); native.show(); ``` -------------------------------- ### Initialize GSettings in Vala for TextViewer.Window Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/saving_state Demonstrates the initialization of a Settings object for the 'com.example.TextViewer' schema within the TextViewer.Window class definition in Vala. This property is declared and instantiated directly in the class, making it available for use. ```vala namespace TextViewer { public class Window : Adw.ApplicationWindow { // ... private Settings settings = new Settings ("com.example.TextViewer"); // ... } } ``` -------------------------------- ### Using Translator Comments in Mallard Documentation Source: https://developer.gnome.org/documentation/guidelines/localization/practices Provides an example of embedding translator comments within a Mallard documentation file. The 'its:locNote' attribute is used for this purpose, ensuring translators receive necessary context. ```xml

Text to translate

``` -------------------------------- ### PtrArray and Array with Free Functions (C) Source: https://developer.gnome.org/documentation/guidelines/programming/memory-management Provides examples of related GLib functions for memory management in dynamic arrays. g_ptr_array_new_with_free_func and g_array_set_clear_func allow specifying functions to free elements when the array is destroyed or elements are removed. ```c // Example usage for GPtrArray (conceptual): // GDestroyNotify element_destroy_func = ...; // GPtrArray *my_ptr_array = g_ptr_array_new_with_free_func(element_destroy_func); // Example usage for GArray (conceptual): // GDestroyNotify element_destroy_func = ...; // GArray *my_array = g_array_new(1, TRUE, sizeof(MyStruct)); // g_array_set_clear_func(my_array, element_destroy_func); ``` -------------------------------- ### Registering a Search Provider Source: https://developer.gnome.org/documentation/tutorials/search-provider Instructions on how to register a new search provider with GNOME Shell by creating a .search-provider.ini file. ```APIDOC ## Registering a New Search Provider ### Description To make your application's search provider known to GNOME Shell, you need to create a key/value configuration file in the `$(datadir)/gnome-shell/search-providers` directory. ### File Format Create a file named `[application_name].search-provider.ini`. For example, if your application is named "Foo Bar" and follows the "Foo" project namespace, the file would be `foo.bar.search-provider.ini`. ### Configuration File Example ```ini [Shell Search Provider] DesktopId=foo.Bar.desktop BusName=foo.Bar ObjectPath=/foo/Bar/SearchProvider Version=2 ``` ### Fields - **DesktopId** (string): The desktop entry ID of your application. This is used by the control center and shell to find the application's icon and name. - **BusName** (string): The D-Bus service name for your search provider. - **ObjectPath** (string): The D-Bus object path for your search provider. - **Version** (integer): The version of the search provider interface being implemented. ### After Registration After creating this file, restart GNOME Shell for the changes to take effect. Subsequent user queries in the shell search entry will then be forwarded to your registered search provider using the specified D-Bus name. ``` -------------------------------- ### Connect Value Changed Signal to Spin Button (Multiple Languages) Source: https://developer.gnome.org/documentation/tutorials/beginners/components/spin_button Illustrates how to connect to the 'value-changed' signal of a GtkSpinButton to react when its value is modified. Examples are provided for CPython, Vala, and JavaScript. ```c // "adj" is defined elsewhere GtkWidget *spin_button = gtk_spin_button_new (adj, 1.0, 0); // "on_value_changed" is defined elsewhere g_signal_connect (spin_button, "value-changed", G_CALLBACK (on_value_changed), NULL); ``` ```python # "adj" is defined elsewhere spin_button = Gtk.SpinButton(adjustment=adj, climb_rate=1.0, digits=0) # "on_value_changed" is defined elsewhere spin_button.connect("value-changed", on_value_changed) ``` ```javascript // "adj" is defined elsewhere var spin_button = new Gtk.SpinButton (adj, 1, 0); // "on_value_changed" is defined elsewhere spin_button.value_changed.connect (on_value_changed); ``` ```javascript // "adj" is defined elsewhere const spin_button = new Gtk.SpinButton(adj, 1, 0); // "on_value_changed" is defined elsewhere spin_button.connect("value_changed", on_value_changed); ``` -------------------------------- ### Define 'Open' Button in UI Definition Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/opening_files This XML snippet defines a GtkButton with the label 'Open' and assigns it an action-name of 'win.open'. It is added as a child to the AdwHeaderBar, positioned at the 'start' edge. ```xml Open win.open True open-menu-symbolic Menu primary_menu ``` -------------------------------- ### Single-Path Cleanup Pattern Example Source: https://developer.gnome.org/documentation/guidelines/programming/memory-management Illustrates the single-path cleanup design pattern in C. All cleanup operations (freeing memory, unreffing objects) are consolidated at a single exit point using goto. Owned variables are initialized to NULL and cleared before returning. ```c GObject * some_function (GError **error) { char *some_str = NULL; /* owned */ GObject *temp_object = NULL; /* owned */ const char *temp_str; GObject *my_object = NULL; /* owned */ GError *child_error = NULL; /* owned */ temp_object = generate_object (); temp_str = "example string"; if (rand ()) { some_str = g_strconcat (temp_str, temp_str, NULL); } else { some_operation_which_might_fail (&child_error); if (child_error != NULL) goto done; my_object = generate_wrapped_object (temp_object); } done: /* Here, @some_str is either NULL or a string to be freed, so can be passed to * g_free() unconditionally. * * Similarly, @temp_object is either NULL or an object to be unreffed, so can * be passed to g_clear_object() unconditionally. */ g_free (some_str); g_clear_object (&temp_object); /* The pattern can also be used to ensure that the function always returns * either an error or a return value (but never both). */ if (child_error != NULL) { g_propagate_error (error, child_error); g_clear_object (&my_object); } return my_object; } ``` -------------------------------- ### GSettings Initialization in TextViewerApplication (Vala) Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/dark_mode Adds a GSettings instance to the TextViewerApplication in Vala. It instantiates a Settings object with the schema ID 'com.example.TextViewer'. ```vala namespace TextViewer { public class Application : Adw.Application { // ... private Settings settings = new Settings ("com.example.TextViewer"); public Application () { Object (application_id: "com.example.TextViewer", flags: ApplicationFlags.FLAGS_NONE); } // ... } } ``` -------------------------------- ### C Example of Ownership Transfer in Memory Management Source: https://developer.gnome.org/documentation/guidelines/programming/memory-management Demonstrates manual memory management in C using ownership concepts. It shows variable ownership, function calls that transfer ownership (like g_value_take_string), and the importance of freeing owned memory before scope exit. ```c char *my_str = NULL; /* owned */ const char *template; /* unowned */ GValue value = G_VALUE_INIT; /* owned */ g_value_init (&value, G_TYPE_STRING); /* Transfers ownership of a string from the function to the variable. */ template = "XXXXXX"; my_str = generate_string (template); /* No ownership transfer. */ print_string (my_str); /* Transfer ownership. We no longer have to free @my_str. */ g_value_take_string (&value, my_str); /* We still have ownership of @value, so free it before it goes out of scope. */ g_value_unset (&value); ``` -------------------------------- ### Actions with Parameters Source: https://developer.gnome.org/documentation/tutorials/notifications Demonstrates how to add actions to notifications that accept parameters, such as passing an application ID to a launch action. ```APIDOC ## Actions with parameters A common pattern is to pass a ‘target’ parameter to the action that contains sufficient details about the notification to let your application react in a meaningful way. As an example, here is how a notification about a newly installed application could provide a launch button: ### CPython Example ```python g_autofree char *title = g_strdup_printf ("%s is now installed", appname); g_autoptr(GNotification) notification = g_notification_new (title); g_notification_add_button_with_target (notification, "Launch", "app.launch", "s", appid); g_application_send_notification (application, "app-installed", notification); ``` ### Vala Example ```vala notification = Gio.Notification() notification.set_title(f"{appname} is now installed") notification.add_button_with_target("Launch", "app.launch", "s", appid) application.send_notification("app-installed", notification) ``` ### JavaScript Example ```javascript string title = appname + " is now installed"; var notification = new Notification (title); notification.add_button_with_target ("Launch", "app.launch", "s", appid); application.send_notification ("app-installed", notification); ``` ### Notes To make this work, your application needs to have a suitable ‘launch’ action that takes the application id as a string parameter: #### CPython ```python static GActionEntry actions[] = { { "launch", launch_application, "s", NULL, NULL }, // ... }; g_action_map_add_action_entries (G_ACTION_MAP (application), actions, G_N_ELEMENTS (actions), application); ``` #### Vala ```vala # The "launch_application" function is defined elsewhere action = Gio.SimpleAction(name="launch") action.connect("activate", launch_application) application.add_action(action) ``` ``` -------------------------------- ### Initialize GSettings in JavaScript for TextViewerWindow Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/saving_state Shows how to initialize a Gio.Settings object with the schema ID 'com.example.TextViewer' as a class property within the TextViewerWindow definition in JavaScript. This makes the settings instance readily available to all methods of the class. ```javascript export const TextViewerWindow = GObject.registerClass({ GTypeName: 'TextViewerWindow', Template: 'resource:///com/example/TextViewer/window.ui', InternalChildren: ['main_text_view', 'open_button', 'cursor_pos'], }, class TextViewerWindow extends Adw.ApplicationWindow { _settings = new Gio.Settings({ schemaId: 'com.example.TextViewer' }); constructor() { // ... } // ... ); ``` -------------------------------- ### Install Icon Cache Update Script Source: https://developer.gnome.org/documentation/tutorials/themed-icons This meson script command ensures that the icon cache is updated for a custom directory. It uses 'gtk-update-icon-cache' with quiet, temporary, and force flags, skipping if a destination directory is not set. ```meson meson.add_install_script( 'gtk-update-icon-cache', '-q', '-t', '-f', customdir, skip_if_destdir: true, ) ``` -------------------------------- ### Assert Main Context Ownership (C) Source: https://developer.gnome.org/documentation/tutorials/main-contexts Provides an example of using g_assert with g_main_context_is_owner to verify that a function is being called within its expected main context. This helps prevent race conditions and ensures correct thread context usage. ```c g_assert (g_main_context_is_owner (expected_main_context)); ``` -------------------------------- ### Create GtkLabel (CPython, Vala, JavaScript) Source: https://developer.gnome.org/documentation/tutorials/beginners/components/label Demonstrates creating GtkLabel widgets with plain text and markup across CPython, Vala, and JavaScript. Markup allows for rich text formatting like bolding and small text. ```c // A plain text label GtkWidget *label = gtk_label_new ("Hello GNOME!"); // A markup label GtkWidget *label = gtk_label_new ("Hello GNOME!"); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); ``` ```python # A plain text label label = Gtk.Label(text="Hello GNOME!") # A markup label label = Gtk.Label(markup="Hello GNOME!") ``` ```javascript // A plain text label var label = new Gtk.Label ("Hello GNOME!"); // A Label that uses markup var markup_label = new Gtk.Label ("Hello GNOME!") { use_markup = true }; ``` ```javascript // A plain text label const label = new Gtk.Label({ label: "Hello GNOME!" }); // A Label that uses markup const markup_label = new Gtk.Label({ label: "Hello GNOME!", use_markup: true, }); ``` -------------------------------- ### Add Open Action and Shortcut in CPython Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/opening_files This snippet demonstrates adding the 'open' action to TextViewerWindow in CPython. It involves modifying the instance initialization function to create and add a GSimpleAction, and setting up 'Ctrl+O' as the accelerator for this action in the application's initialization. ```c static void text_viewer_window__open_file_dialog (GAction *action, GVariant *parameter, TextViewerWindow *self); static void text_viewer_window_init (TextViewerWindow *self) { gtk_widget_init_template (GTK_WIDGET (self)); g_autoptr (GSimpleAction) open_action = g_simple_action_new ("open", NULL); g_signal_connect (open_action, "activate", G_CALLBACK (text_viewer_window__open_file_dialog), self); g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (open_action)); } static void text_viewer_application_init (TextViewerApplication *self) { // ... gtk_application_set_accels_for_action (GTK_APPLICATION (self), "win.open", (const char *[]) { "o", NULL, }); } ``` -------------------------------- ### C Coding Style: GNU Indentation Example Source: https://developer.gnome.org/documentation/guidelines/programming/coding-style Illustrates the GNU coding style for C, featuring 2-space indentation for each new level and placing opening and closing braces on their own lines. This style is used in the GTK library. ```c for (i = 0; i < num_elements; i++) { foo[i] = foo[i] + 42; if (foo[i] < 35) { printf ("Foo!"); foo[i]--; } else { printf ("Bar!"); foo[i]++; } } ``` -------------------------------- ### Adding Choices to File Chooser Dialog (Vala) Source: https://developer.gnome.org/documentation/tutorials/beginners/components/file_dialog Provides examples in Vala for adding custom choices to a GtkFileChooser. It demonstrates creating a simple boolean choice and a more complex choice with multiple predefined options, each with a corresponding user-facing label. ```vala # Boolean choice file_chooser.add_choice("validate", "Enable validation on load", None, None) # Multiple choices file_chooser.add_choice("action", "Action when loading", ["live", "laugh", "love"], ["Live", "Laugh", "Love"]) ``` -------------------------------- ### Add Open Action and Shortcut in Python Source: https://developer.gnome.org/documentation/tutorials/beginners/getting_started/opening_files This snippet shows how to implement the 'open' action in Python for TextViewerWindow. It involves creating a Gio.SimpleAction, connecting its activation signal to a handler, and adding it to the window. The 'Ctrl+O' shortcut is then set for the 'win.open' action in the Application's initialization. ```python from gi.repository import Adw, Gio, Gtk @Gtk.Template(resource_path='/com/example/TextViewer/window.ui') class TextViewerWindow(Gtk.ApplicationWindow): __gtype_name__ = 'TextViewerWindow' main_text_view = Gtk.Template.Child() open_button = Gtk.Template.Child() def __init__(self, **kwargs): super().__init__(**kwargs) open_action = Gio.SimpleAction(name="open") open_action.connect("activate", self.open_file_dialog) self.add_action(open_action) def open_file_dialog(self, action, _): pass class Application(Adw.Application): def __init__(self): super().__init__(application_id='com.example.TextViewer', flags=Gio.ApplicationFlags.FLAGS_NONE) # ... self.set_accels_for_action('win.open', ['o']) ``` -------------------------------- ### Apply 'suggested-action' Style Class (UI) Source: https://developer.gnome.org/documentation/tutorials/beginners/components/button Applies the 'suggested-action' CSS class to a GtkButton within a UI file, visually styling it as a primary or recommended action, typically with a distinct color like blue. This aids in guiding user choices. ```xml Apply ```