summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlukefromdc <[email protected]>2023-12-15 02:06:53 -0500
committerLuke from DC <[email protected]>2024-01-17 00:33:59 +0000
commit3d06d8b6dd1a26c26f34816a347524aeff3430b2 (patch)
tree109aa2a1f19c02490c3ef0115256cd8ec18cc149 /src
parent8bb93666b35ee6277071d1b5ab4d52ae57d06975 (diff)
downloadcaja-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')
-rw-r--r--src/caja-desktop-window.c5
-rw-r--r--src/file-manager/Makefile.am2
-rw-r--r--src/file-manager/fm-desktop-icon-view.c28
-rw-r--r--src/file-manager/fm-desktop-wayland-bg-dialog.c418
-rw-r--r--src/file-manager/fm-desktop-wayland-bg-dialog.h28
5 files changed, 475 insertions, 6 deletions
diff --git a/src/caja-desktop-window.c b/src/caja-desktop-window.c
index 6188fa63..662c2472 100644
--- a/src/caja-desktop-window.c
+++ b/src/caja-desktop-window.c
@@ -390,10 +390,12 @@ realize (GtkWidget *widget)
G_CALLBACK (caja_desktop_window_screen_size_changed), window);
}
+/* Should only reached in x11*/
static gboolean
draw (GtkWidget *widget,
cairo_t *cr)
{
+ g_assert (GDK_IS_X11_DISPLAY (gdk_display_get_default()));
eel_background_draw (widget, cr);
return GTK_WIDGET_CLASS (caja_desktop_window_parent_class)->draw (widget, cr);
}
@@ -415,6 +417,9 @@ caja_desktop_window_class_init (CajaDesktopWindowClass *klass)
wclass->realize = realize;
wclass->unrealize = unrealize;
wclass->map = map;
+ /*Drawing the desktop background from here gives a black background in wayland
+ *So manage desktop background from the icon container as in navigation windows
+ */
if (GDK_IS_X11_DISPLAY (gdk_display_get_default()))
wclass->draw = draw;
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