Skip to content

Add AdwMessageDialog

Alice Mikhaylenko requested to merge wip/exalm/message-dialog into main

A GtkMessageDialog replacement.


  • It's adaptive and constrained within the parent:
  • Fixes a few papercuts (e.g. the whole dialog is draggable, the text is properly centered etc
  • Hopefully has a better API: no direct widget access, no GtkResponseType, no GtkDialog inheritance. Instead there are frequently used things like a proper way to mark responses as destructive.

Programmatic usage:

  GtkWidget *dialog;

  dialog = adw_message_dialog_new (parent,
                                   _("Save Changes?"),
                                   _("Open document contains unsaved changes. Changes which are not saved will be permanently lost."));

  adw_message_dialog_add_responses (ADW_MESSAGE_DIALOG (dialog),
                                    "cancel", _("_Cancel"),
                                    "discard", _("_Discard All"),
                                    "save", _("_Save"),

  adw_message_dialog_set_response_enabled (ADW_MESSAGE_DIALOG (dialog), "save", FALSE);
  adw_message_dialog_set_response_appearance (ADW_MESSAGE_DIALOG (dialog), "discard", ADW_RESPONSE_DESTRUCTIVE);
  adw_message_dialog_set_response_appearance (ADW_MESSAGE_DIALOG (dialog), "save", ADW_RESPONSE_SUGGESTED);

  adw_message_dialog_set_default_response (ADW_MESSAGE_DIALOG (dialog), "save");
  adw_message_dialog_set_close_response (ADW_MESSAGE_DIALOG (dialog), "close");

  g_signal_connect (dialog, "response", G_CALLBACK (response_cb), self);

  gtk_window_present (GTK_WINDOW (dialog));

GtkBuilder usage:

  <object class="AdwMessageDialog">
    <property name="text" translatable="yes">Save Changes?</property>
    <property name="secondary-text" translatable="yes">Open document contains unsaved changes. Changes which are not saved will be permanently lost.</property>
    <property name="default-response">save</property>
    <property name="close-response">cancel</property>
    <signal name="response" handler="response_cb"/>
      <response id="cancel" translatable="yes">_Cancel</response>
      <response id="discard" translatable="yes" appearance="destructive">_Discard</response>
      <response id="save" translatable="yes" enabled="false" appearance="suggested">_Save</response>

Not showcased are:

  • :extra-child to add a widget (like the entry on those screenshots)
  • adw_message_dialog_set_response_label() to change response labels in runtimes (I've seen a recent gnome-text-editor mockup that needed that)
  • adw_message_dialog_format_text/markup(), format_secondary_text/markup(). They first 2 are not a part of _new() anymore, instead _new() params are nullable:
  dialog = adw_message_dialog_new (parent, NULL, NULL);
  adw_message_dialog_format_text (_("Something %s", "something"));
  adw_message_dialog_format_secondary_markup (_("Something <b>%s</b>", "something"));
  • The ::response signal is detailed with the response ID being the detail. So it's possible to do things like:
  g_signal_connect (dialog, "response::cancel", G_CALLBACK (response_cancel_cb), self);
  g_signal_connect (dialog, "response::discard", G_CALLBACK (response_discard_cb), self);
  g_signal_connect (dialog, "response::save", G_CALLBACK (response_save_cb), self);

if you really want to.


  • Docs
  • Tests
  • Simplify UI file and styles, try to decouple them from GtkMessageDialog
  • Finish the demo
  • Try to move focus when switching between wide and narrow modes
Edited by Alice Mikhaylenko

Merge request reports