diff options
author | lukefromdc <[email protected]> | 2023-12-15 02:06:53 -0500 |
---|---|---|
committer | Luke from DC <[email protected]> | 2024-01-17 00:33:59 +0000 |
commit | 3d06d8b6dd1a26c26f34816a347524aeff3430b2 (patch) | |
tree | 109aa2a1f19c02490c3ef0115256cd8ec18cc149 /src/file-manager | |
parent | 8bb93666b35ee6277071d1b5ab4d52ae57d06975 (diff) | |
download | caja-3d06d8b6dd1a26c26f34816a347524aeff3430b2.tar.bz2 caja-3d06d8b6dd1a26c26f34816a347524aeff3430b2.tar.xz |
Manage desktop backgrounds when running in wayland
*Draw the background on the desktop window, using the same code as on navigation windows to bypass the no-root-window issue.
*Works from caja's "Change Desktop Background" menu item, from caja-extensions "set as wallpaper" and with changing the background in dconf-editor.
*All background options available in x11 supported in wayland, UI is new for wayland
*Apply changes immediately, keep the dialog open until closed by user
*Let users see changes in realtime while keeping the dialog open
*Preview both colors and pictures
*Add ability to apply changes from either combobox including using any image saved from when dialog was opened
*Add tooltips to the buttons, filepicker, and comboboxes
Diffstat (limited to 'src/file-manager')
-rw-r--r-- | src/file-manager/Makefile.am | 2 | ||||
-rw-r--r-- | src/file-manager/fm-desktop-icon-view.c | 28 | ||||
-rw-r--r-- | src/file-manager/fm-desktop-wayland-bg-dialog.c | 418 | ||||
-rw-r--r-- | src/file-manager/fm-desktop-wayland-bg-dialog.h | 28 |
4 files changed, 470 insertions, 6 deletions
diff --git a/src/file-manager/Makefile.am b/src/file-manager/Makefile.am index 98173976..3707409c 100644 --- a/src/file-manager/Makefile.am +++ b/src/file-manager/Makefile.am @@ -23,6 +23,8 @@ libcaja_file_manager_la_SOURCES = \ fm-actions.h \ fm-desktop-icon-view.c \ fm-desktop-icon-view.h \ + fm-desktop-wayland-bg-dialog.c \ + fm-desktop-wayland-bg-dialog.h \ fm-directory-view.c \ fm-directory-view.h \ fm-widget-view.c \ diff --git a/src/file-manager/fm-desktop-icon-view.c b/src/file-manager/fm-desktop-icon-view.c index 3a88b091..0d0c034a 100644 --- a/src/file-manager/fm-desktop-icon-view.c +++ b/src/file-manager/fm-desktop-icon-view.c @@ -62,6 +62,12 @@ #include "fm-desktop-icon-view.h" #include "fm-actions.h" +#ifdef HAVE_WAYLAND +#include <gdk/gdkwayland.h> +#include "fm-desktop-wayland-bg-dialog.h" + +#endif + /* Timeout to check the desktop directory for updates */ #define RESCAN_TIMEOUT 4 @@ -707,12 +713,22 @@ action_change_background_callback (GtkAction *action, gpointer data) { g_assert (FM_DIRECTORY_VIEW (data)); - - caja_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (data)), - _("Background"), - "mate-appearance-properties", - FALSE, - "--show-page=background", NULL); +#ifdef HAVE_WAYLAND + /*Get the new background and switch to it in wayland*/ + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default())) + { + wayland_bg_dialog_new (); + } + else +#endif + /*Get the new background and switch to it in x11*/ + { + caja_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (data)), + _("Background"), + "mate-appearance-properties", + FALSE, + "--show-page=background", NULL); + } } static void diff --git a/src/file-manager/fm-desktop-wayland-bg-dialog.c b/src/file-manager/fm-desktop-wayland-bg-dialog.c new file mode 100644 index 00000000..53c6cdb4 --- /dev/null +++ b/src/file-manager/fm-desktop-wayland-bg-dialog.c @@ -0,0 +1,418 @@ + +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* fm-icon-container.h - the container widget for file manager icons + + Copyright (C) 2024 Luke <[email protected]> + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + + Author: <[email protected]> +*/ + +#include <config.h> +#include <fcntl.h> +#include <limits.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <X11/Xatom.h> +#include <gtk/gtk.h> +#include <gdk/gdkx.h> +#include <glib/gi18n.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <eel/eel-glib-extensions.h> +#include <eel/eel-gtk-extensions.h> +#include <eel/eel-vfs-extensions.h> + +#include <libcaja-private/caja-directory-background.h> +#include <libcaja-private/caja-global-preferences.h> + +#include "fm-desktop-icon-view.h" +#include "fm-desktop-wayland-bg-dialog.h" + + +#ifdef HAVE_WAYLAND + +GSettings *background_settings; +GtkWidget *filebutton; +GtkWidget *preview; +GtkWidget *preview_image; +const gchar *filename; +GdkRGBA color1, color2; +const gchar *primary_color_str, *secondary_color_str, *shading_type; + +static void +update_preview() +{ + static GtkCssProvider *provider; + gchar *css; + GString *string; + + if (!provider) + provider = gtk_css_provider_new (); + + /*Build a color preview using a cssprovider due to requirement to handle RBGA values*/ + string = g_string_new(NULL); + g_string_append (string, "#caja-wayland-bg-preview {"); + + if (strcmp (shading_type, "vertical-gradient") == 0) + g_string_append (string, "background-image: linear-gradient(to bottom,"); + + else if (strcmp (shading_type, "horizontal-gradient") == 0) + g_string_append (string, "background-image: linear-gradient(to right,"); + + else + { + g_string_append (string, "background-color:"); + g_string_append (string, primary_color_str); + } + + if ((strcmp (shading_type, "vertical-gradient") == 0) || + (strcmp (shading_type, "horizontal-gradient") == 0)) + { + g_string_append (string, primary_color_str); + g_string_append (string, ","); + g_string_append (string, secondary_color_str); + g_string_append (string, ");"); + } + g_string_append (string, "}"); + + css = g_string_free (string, FALSE); + gtk_style_context_add_provider (gtk_widget_get_style_context (preview), + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + + gtk_css_provider_load_from_data (provider, css, -1, NULL); + + if ((!filename) || (strcmp (filename, "") == 0) || (strcmp (filename, " ") == 0)) + gtk_image_clear(GTK_IMAGE(preview_image)); + + else + { + GdkRectangle geometry = {0}; + GdkPixbuf *pixbuf; + GdkMonitor *monitor; + GdkDisplay *display; + + display = gdk_screen_get_display (gdk_screen_get_default()); + monitor = gdk_display_get_monitor (display, 0); + gdk_monitor_get_geometry (monitor, &geometry); + + gtk_style_context_remove_provider (gtk_widget_get_style_context (preview), + GTK_STYLE_PROVIDER (provider)); + + gtk_widget_set_size_request (preview, geometry.width / 5, geometry.height / 5); + + pixbuf = gdk_pixbuf_new_from_file_at_scale (filename, geometry.width / 5, + geometry.height / 5, FALSE, NULL); + + gtk_image_set_from_pixbuf (GTK_IMAGE (preview_image), pixbuf); + g_object_unref(pixbuf); + } +} + +static void +update_primary_color(GtkWidget *colorbutton1) +{ + GdkRGBA color1; + + filename = ""; + gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (colorbutton1), &color1); + primary_color_str = gdk_rgba_to_string (&color1); + g_settings_set_string (background_settings, + "primary-color", primary_color_str); + + g_settings_set_string (background_settings, + "picture-filename", ""); + update_preview(); +} + +static void +update_secondary_color(GtkWidget *colorbutton2) +{ + GdkRGBA color2; + + filename = ""; + gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (colorbutton2), &color2); + secondary_color_str = gdk_rgba_to_string (&color2); + g_settings_set_string (background_settings, + "secondary-color", secondary_color_str); + + g_settings_set_string (background_settings, + "picture-filename", ""); + update_preview(); + +} + +static void +update_color_background_options (GtkWidget *colorbox) +{ + filename = ""; + + shading_type = gtk_combo_box_get_active_id (GTK_COMBO_BOX (colorbox)); + /*write to gsettings*/ + g_settings_set_string (background_settings, + "color-shading-type", shading_type); + g_settings_set_string (background_settings, + "picture-filename", ""); + update_preview(); +} + +static void +update_image_background_options(GtkWidget *stylebox) +{ + const gchar *options; + options = gtk_combo_box_get_active_id (GTK_COMBO_BOX(stylebox)); + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filebutton)); + if ((!filename) || (strcmp (filename, " ") == 0)) + filename = ""; + + /*write to gsettings*/ + g_settings_set_string (background_settings, + "picture-options", options); + + g_settings_set_string (background_settings, + "picture-filename", filename); + update_preview(); +} + +static void +update_background_image (GtkWidget *filebutton) +{ + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filebutton)); + if (strcmp (filename, " ") == 0) + filename = ""; + + /*write to gsettings*/ + g_settings_set_string (background_settings, + "picture-filename", filename); + update_preview (); +} + +void +wayland_bg_dialog_new (void) +{ + GtkWidget *dialog, *box, *vbox1, *vbox2, *hbox1, *hbox2; + GtkWidget *close_button, *colorlabel, *stylelabel; + GtkWidget *filelabel, *stylebox; + GtkWidget *colorbox, *colorbutton1, *colorbutton2; + const gchar *options; + GdkRectangle geometry = {0}; + GdkDisplay *display; + GdkMonitor *monitor; + + background_settings = g_settings_new ("org.mate.background"); + + filename = g_settings_get_string (background_settings, + "picture-filename"); + + options = g_settings_get_string (background_settings, + "picture-options"); + + primary_color_str = g_settings_get_string (background_settings, + "primary-color"); + + secondary_color_str = g_settings_get_string (background_settings, + "secondary-color"); + + shading_type = g_settings_get_string (background_settings, + "color-shading-type"); + + dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog), + _("Desktop Background Preferences")); + + gtk_window_set_transient_for (GTK_WINDOW (dialog), NULL); + + /*Image Style Combobox*/ + stylebox = gtk_combo_box_text_new (); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (stylebox), + "wallpaper", "Tile" ); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (stylebox), + "zoom", "Zoom" ); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (stylebox), + "centered", "Center"); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (stylebox), + "scaled", "Scale"); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (stylebox), + "stretched", "Stretch"); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (stylebox), + "spanned", "Span"); + + gtk_combo_box_set_active_id (GTK_COMBO_BOX (stylebox), options); + + g_signal_connect (stylebox, "changed", + G_CALLBACK (update_image_background_options), stylebox); + + gtk_widget_set_tooltip_text (stylebox, "Image Aspect Ratio and Size. \n" + "Changes applied immediately"); + + /*Color Combobox*/ + colorlabel = gtk_label_new ("Colors:"); + colorbox = gtk_combo_box_text_new (); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (colorbox), + "solid", "Solid color" ); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (colorbox), + "horizontal-gradient", "Horizontal gradient" ); + + gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (colorbox), + "vertical-gradient", "Vertical gradient"); + + gtk_combo_box_set_active_id (GTK_COMBO_BOX (colorbox), shading_type); + + g_signal_connect (colorbox, "changed", + G_CALLBACK (update_color_background_options), colorbox); + + gtk_widget_set_tooltip_text (colorbox, "Use gradient or solid color. \n" + "Changes applied immediately"); + + colorbutton1 = gtk_color_button_new (); + colorbutton2 = gtk_color_button_new (); + gtk_widget_set_tooltip_text (colorbutton1, "Color for gradient top/left or solid color \n" + "Applies on selecting any color"); + + gtk_widget_set_tooltip_text (colorbutton2, "Color for gradient bottom/right\n" + "Applies on selecting any color"); + + + if (!(gdk_rgba_parse (&color1, primary_color_str))) + gdk_rgba_parse (&color1, "rgb(88,145,188)"); + + if (!(gdk_rgba_parse (&color2, secondary_color_str))) + gdk_rgba_parse (&color2, "rgb(60,143,37)"); + + gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (colorbutton1), &color1); + gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (colorbutton2), &color2); + + g_signal_connect (colorbutton1, "color-set", + G_CALLBACK (update_primary_color), colorbutton1); + + g_signal_connect (colorbutton2, "color-set", + G_CALLBACK (update_secondary_color), colorbutton1); + + /*file chooser and it's label for the color bg case*/ + filelabel = gtk_label_new ("Image:"); + stylelabel = gtk_label_new ("Style:"); + filebutton = gtk_file_chooser_button_new (_("Select a file"), + GTK_FILE_CHOOSER_ACTION_OPEN); + + gtk_widget_set_tooltip_text (filebutton, "Image for desktop background. \n" + "Applies on opening image"); + + gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (filebutton), 16); + + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filebutton), + filename); + + gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (filebutton), + "Select a File"); + + /* If the last background was an image show the user the default background directory*/ + if ((!filename) || (strcmp (filename, "") == 0) || (strcmp (filename, " ") == 0)) + { + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filebutton), "/usr/share/backgrounds/"); + } + + preview = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + + /*Get the size and shape of the desktop*/ + display = gdk_screen_get_display (gdk_screen_get_default()); + monitor = gdk_display_get_monitor (display, 0); + gdk_monitor_get_geometry (monitor, &geometry); + + gtk_widget_set_size_request (preview, geometry.width / 5, geometry.height / 5); + gtk_widget_set_name (GTK_WIDGET (preview), "caja-wayland-bg-preview"); + preview_image = gtk_image_new (); + update_preview (); + + g_signal_connect (filebutton, "file-set", + G_CALLBACK (update_background_image), NULL); + + /*Apply and Cancel buttons */ + close_button = gtk_button_new_with_mnemonic (_("_Close")); + + gtk_button_set_image (GTK_BUTTON (close_button), + gtk_image_new_from_icon_name ("gtk-cancel", GTK_ICON_SIZE_BUTTON)); + + gtk_button_set_use_underline (GTK_BUTTON (close_button), TRUE); + gtk_widget_set_can_default (close_button, TRUE); + + /*Prepare the boxes to pack all this into*/ + box = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + + /*Pack the filechooser and image options*/ + gtk_box_pack_start (GTK_BOX (hbox1), stylelabel, FALSE, FALSE, 7); + gtk_box_pack_start (GTK_BOX (hbox1), stylebox, FALSE, FALSE, 3); + gtk_box_pack_end (GTK_BOX (hbox1), filebutton, FALSE, FALSE, 5); + gtk_box_pack_end (GTK_BOX (hbox1), filelabel, FALSE, FALSE, 2); + + /*Pack the colorpickers and color options*/ + + gtk_box_pack_start (GTK_BOX (hbox2), colorbox, FALSE, FALSE, 7); + gtk_box_pack_end (GTK_BOX (hbox2), colorbutton2, FALSE, FALSE, 5); + gtk_box_pack_end (GTK_BOX (hbox2), colorbutton1, FALSE, FALSE, 2); + gtk_box_pack_end (GTK_BOX (hbox2), colorlabel, FALSE, FALSE, 2); + + gtk_box_pack_start (GTK_BOX (preview), preview_image, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox2), preview, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0); + + /*Pack the other boxes into the final vertical box*/ + gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 20); + gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, FALSE, 5); + + /*Pack the final vertical box into the content area*/ + gtk_box_pack_start (GTK_BOX (box), vbox1, FALSE, FALSE, 0); + + /*Pack the close action area*/ + + gtk_dialog_add_action_widget (GTK_DIALOG (dialog), + close_button, + GTK_RESPONSE_APPLY); + + gtk_widget_show_all (dialog); + + /*Run the dialog*/ + gtk_dialog_run (GTK_DIALOG (dialog)); + /*cleanup*/ + g_signal_handlers_disconnect_by_func (stylebox, update_image_background_options, stylebox); + g_signal_handlers_disconnect_by_func (colorbox, update_color_background_options, colorbox); + g_signal_handlers_disconnect_by_func (colorbutton1, update_primary_color, colorbutton1); + g_signal_handlers_disconnect_by_func (colorbutton2, update_primary_color, colorbutton2); + g_signal_handlers_disconnect_by_func (filebutton, update_background_image, NULL); + + g_object_unref (background_settings); + gtk_widget_destroy (dialog); +} +#endif + diff --git a/src/file-manager/fm-desktop-wayland-bg-dialog.h b/src/file-manager/fm-desktop-wayland-bg-dialog.h new file mode 100644 index 00000000..65858c05 --- /dev/null +++ b/src/file-manager/fm-desktop-wayland-bg-dialog.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* fm-icon-container.h - the container widget for file manager icons + + Copyright (C) 2024 Luke <[email protected]> + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + + Author: Luke <[email protected]> +*/ +#ifdef HAVE_WAYLAND +#include "fm-desktop-icon-view.h" + +void wayland_bg_dialog_new (void); +#endif |