From 472d7c466d33bd1fe4cd293b354e52bf16384520 Mon Sep 17 00:00:00 2001 From: Gordon Norman Squash Date: Tue, 10 Sep 2024 01:28:29 -0400 Subject: Initial commit This is where I have started tracking development with Git. I declare this as version 0.89. --- patches/dialogs.c | 451 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 451 insertions(+) create mode 100644 patches/dialogs.c (limited to 'patches/dialogs.c') diff --git a/patches/dialogs.c b/patches/dialogs.c new file mode 100644 index 0000000..5118fc3 --- /dev/null +++ b/patches/dialogs.c @@ -0,0 +1,451 @@ +/* Dialogs: + * From gtk3-classic patches: + * appearance__message-dialogs.patch + * appearance__file-chooser.patch + * appearance__print-dialog.patch + * fixes__wayland_dialogs_header_setting.patch + * file-chooser__eject-button.patch + * file-chooser__typeahead.patch + * + * Restores the classic appearance of message, print, and file dialogs. + * Forces dialogs to use the traditional action area for their buttons, + * instead of putting the buttons in a headerbar -- even on Wayland. + * Also makes some behavioural changes to file chooser widgets (and thus + * by extension file dialogs). + */ + + +#include +#include +#include +#include + +#include + +#include + + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "Gtk3-Classic::Dialogs" + + +#define MESSAGE_DIALOG_CSS \ + "messagedialog > *,\n" \ + "messagedialog buttonbox.dialog-action-area,\n" \ + "messagedialog box.dialog-action-box\n" \ + "{\n" \ + " margin: 0;\n" \ + " margin-top: 0;\n" \ + " padding: 0;\n" \ + "}\n" + +#define PRINT_DIALOG_CSS \ + "printdialog box.dialog-action-box\n" \ + "{\n" \ + " margin: 0;\n" \ + "}\n" + +#define FILE_CHOOSER_CSS \ + "/* Prefer full-color icons to symbolic ones */\n" \ + "filechooser .sidebar-icon,\n" \ + "filechooser .path-bar,\n" \ + "filechooser .path-bar + button\n" \ + "{\n" \ + " opacity: 1;\n" \ + " -gtk-icon-style: regular;\n" \ + "}\n" \ + "\n" \ + "/* Hide the Eject / Unmount buttons next to volumes in the sidebar */\n" \ + "filechooser .sidebar-button\n" \ + "{\n" \ + " opacity: 0;\n" \ + "}\n" + + +static void apply_dialog_css (GtkWidget * dialog); +static GtkWidget * find_widget_by_name (GtkWidget * start, + const char * name); + + +INTERCEPTED_CLASS_METHOD (gtk_settings, constructed, + (GObject * object), + void) + + +INTERCEPTED_CLASS_METHOD (gtk_message_dialog, constructed, + (GObject * object), + void) + +INTERCEPTED_CLASS_METHOD (gtk_message_dialog, notify, + (GObject * object, + GParamSpec * pspec), + void) + + +INTERCEPTED_CLASS_METHOD (gtk_print_unix_dialog, constructed, + (GObject * object), + void) + + +INTERCEPTED_CLASS_METHOD (gtk_file_chooser_widget, constructed, + (GObject * object), + void) + +static void +filechooser_treeview_search_column_changed (GObject * object, + GParamSpec * pspec, + gpointer data); + +static void +filechooser_search_entry_map (GtkWidget * widget, + gpointer data); + +static void +filechooser_search_entry_unmap (GtkWidget * widget, + gpointer data); + + +void dialogs_init () +{ + { + GtkSettingsClass * gtk_settings_class = + g_type_class_ref (GTK_TYPE_SETTINGS); + + INTERCEPT_CLASS_METHOD (gtk_settings, G_OBJECT_CLASS, + constructed) + + g_type_class_unref (gtk_settings_class); + } + + + { + GtkMessageDialogClass * gtk_message_dialog_class = + g_type_class_ref (GTK_TYPE_MESSAGE_DIALOG); + + INTERCEPT_CLASS_METHOD (gtk_message_dialog, G_OBJECT_CLASS, + constructed) + INTERCEPT_CLASS_METHOD (gtk_message_dialog, G_OBJECT_CLASS, + notify); + + g_type_class_unref (gtk_message_dialog_class); + } + + + { + GtkPrintUnixDialogClass * gtk_print_unix_dialog_class = + g_type_class_ref (GTK_TYPE_PRINT_UNIX_DIALOG); + + INTERCEPT_CLASS_METHOD (gtk_print_unix_dialog, G_OBJECT_CLASS, + constructed) + + g_type_class_unref (gtk_print_unix_dialog_class); + } + + + { + GtkFileChooserWidgetClass * gtk_file_chooser_widget_class = + g_type_class_ref (GTK_TYPE_FILE_CHOOSER_WIDGET); + + INTERCEPT_CLASS_METHOD (gtk_file_chooser_widget, + G_OBJECT_CLASS, constructed) + + g_type_class_unref (gtk_file_chooser_widget_class); + } +} + + +static void +new_gtk_settings_constructed +(GObject * object) +{ + CALL_ORIGINAL_CLASS_METHOD (gtk_settings, constructed, (object)); + + g_object_set (object, "gtk-dialogs-use-header", FALSE, NULL); +} + + +static void +new_gtk_message_dialog_constructed +(GObject * object) +{ + GtkWidget * internal_vbox; + GtkWidget * box; + GtkWidget * message_area; + GtkWidget * label; + GtkWidget * secondary_label; + GtkWidget * action_area; + + + CALL_ORIGINAL_CLASS_METHOD (gtk_message_dialog, constructed, (object)); + + apply_dialog_css (GTK_WIDGET (object)); + + gtk_container_set_border_width (GTK_CONTAINER (object), 5); + + internal_vbox = find_widget_by_name (GTK_WIDGET (object), + "dialog-vbox1"); + gtk_container_set_border_width (GTK_CONTAINER (internal_vbox), 2); + gtk_box_set_spacing (GTK_BOX (internal_vbox), 8); + + box = find_widget_by_name (internal_vbox, "box"); + gtk_widget_set_margin_start (box, 2); + gtk_widget_set_margin_end (box, 2); + gtk_container_set_border_width (GTK_CONTAINER (box), 5); + gtk_box_set_spacing (GTK_BOX (box), 12); + + message_area = find_widget_by_name (box, "message_area"); + gtk_box_set_spacing (GTK_BOX (message_area), 12); + + label = find_widget_by_name (message_area, "label"); + secondary_label = find_widget_by_name (message_area, + "secondary_label"); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_widget_set_halign (secondary_label, GTK_ALIGN_START); + gtk_label_set_xalign (GTK_LABEL (label), 0); + gtk_label_set_xalign (GTK_LABEL (secondary_label), 0); + + action_area = find_widget_by_name (GTK_WIDGET (object), "action_area"); + gtk_container_set_border_width (GTK_CONTAINER (action_area), 5); + gtk_box_set_spacing (GTK_BOX (action_area), 6); + gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area), + GTK_BUTTONBOX_END); +} + + +static void +new_gtk_message_dialog_notify +(GObject * object, + GParamSpec * pspec) +{ + GtkMessageType message_type; + const char * icon_name; + GtkWidget * image; + GtkMessageType image_message_type; + + + CALL_ORIGINAL_CLASS_METHOD (gtk_message_dialog, + notify, (object, pspec)); + + + if (strcmp (pspec->name, "message-type") != 0) + return; + + g_object_get (object, "message-type", &message_type, NULL); + g_object_get (object, "image", &image, NULL); + + if (image != NULL) + { + image_message_type = GPOINTER_TO_INT ( + g_object_get_data (G_OBJECT (image), "message-type")) - 1; + if (image_message_type == message_type) + return; + } + + switch (message_type) + { + case GTK_MESSAGE_INFO: + icon_name = "dialog-information"; + break; + case GTK_MESSAGE_WARNING: + icon_name = "dialog-warning"; + break; + case GTK_MESSAGE_QUESTION: + icon_name = "dialog-question"; + break; + case GTK_MESSAGE_ERROR: + icon_name = "dialog-error"; + break; + default: + return; + } + + image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG); + gtk_widget_show (image); + g_object_set_data (G_OBJECT (image), "message-type", + GINT_TO_POINTER (message_type + 1)); + + g_object_freeze_notify (object); + g_object_set (object, "image", image, NULL); + g_object_set (object, "message-type", message_type, NULL); + g_object_thaw_notify (object); +} + + +static void +new_gtk_print_unix_dialog_constructed +(GObject * object) +{ + GtkWidget * internal_vbox; + GtkWidget * box; + GtkWidget * notebook; + + + CALL_ORIGINAL_CLASS_METHOD (gtk_print_unix_dialog, + constructed, (object)); + + apply_dialog_css (GTK_WIDGET (object)); + + gtk_container_set_border_width (GTK_CONTAINER (object), 5); + + internal_vbox = find_widget_by_name (GTK_WIDGET (object), + "dialog-vbox1"); + gtk_container_set_border_width (GTK_CONTAINER (internal_vbox), 2); + + box = find_widget_by_name (internal_vbox, "box1"); + gtk_container_set_border_width (GTK_CONTAINER (box), 5); + + notebook = find_widget_by_name (box, "notebook"); + gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), TRUE); +} + + +static void +new_gtk_file_chooser_widget_constructed +(GObject * object) +{ + GtkWidget * treeview; + GtkWidget * search_entry; + + + CALL_ORIGINAL_CLASS_METHOD (gtk_file_chooser_widget, + constructed, (object)); + + + apply_dialog_css (GTK_WIDGET (object)); + + + treeview = find_widget_by_name (GTK_WIDGET (object), + "browse_files_tree_view"); + + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE); + + g_signal_connect (G_OBJECT (treeview), "notify::search-column", + G_CALLBACK (filechooser_treeview_search_column_changed), NULL); + + search_entry = find_widget_by_name (GTK_WIDGET (object), + "search_entry"); + + g_signal_connect (G_OBJECT (search_entry), "map", + G_CALLBACK (filechooser_search_entry_map), + treeview); + + g_signal_connect (G_OBJECT (search_entry), "unmap", + G_CALLBACK (filechooser_search_entry_unmap), + treeview); +} + + +static void +filechooser_treeview_search_column_changed +(GObject * object, + GParamSpec * pspec, + gpointer data) +{ + (void) pspec; + (void) data; + + + if (gtk_tree_view_get_search_column (GTK_TREE_VIEW (object)) == -1) + gtk_tree_view_set_search_column (GTK_TREE_VIEW (object), 0); +} + + +static void filechooser_search_entry_map +(GtkWidget * widget, + gpointer data) +{ + (void) widget; + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (data), FALSE); +} + +static void filechooser_search_entry_unmap +(GtkWidget * widget, + gpointer data) +{ + (void) widget; + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (data), TRUE); +} + + +/* Helper functions */ + +static void apply_dialog_css (GtkWidget * dialog) +{ + GdkScreen * screen; + gboolean dialog_css_applied; + GtkCssProvider * provider; + + + screen = gtk_widget_get_screen (dialog); + dialog_css_applied = + GPOINTER_TO_INT (g_object_get_data (G_OBJECT (screen), + "dialog-css-applied")); + if (! dialog_css_applied) + { + provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, + MESSAGE_DIALOG_CSS + PRINT_DIALOG_CSS + FILE_CHOOSER_CSS, + -1, NULL); + gtk_style_context_add_provider_for_screen (screen, + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); + g_object_set_data (G_OBJECT (screen), + "dialog-css-applied", + GINT_TO_POINTER (TRUE)); + } +} + + +static void add_widget_to_list (GtkWidget * widget, gpointer data) +{ + GSList ** list = data; + + + *list = g_slist_append (*list, widget); +} + + +static GtkWidget * +find_widget_by_name +(GtkWidget * start, + const char * name) +{ + const char * widget_name; + GtkWidget * widget; + GSList * list; + GSList * list_iter; + + + if (GTK_IS_BUILDABLE (start)) + { + widget_name = gtk_buildable_get_name (GTK_BUILDABLE (start)); + if (widget_name != NULL && strcmp (widget_name, name) == 0) + return start; + } + + if (GTK_IS_CONTAINER (start)) + { + list = NULL; + gtk_container_forall (GTK_CONTAINER (start), + add_widget_to_list, + &list); + for (list_iter = list; + list_iter != NULL; + list_iter = list_iter->next) + { + widget = + find_widget_by_name (GTK_WIDGET (list_iter->data), + name); + if (widget != NULL) + break; + } + + g_slist_free (list); + return widget; + } + + + return NULL; +} -- cgit