can't figure out wallpaper issue, use SWWW for example instead

This commit is contained in:
rozodru 2025-08-06 06:58:28 -04:00
parent fb442ec54c
commit ce8248db8a
5 changed files with 98 additions and 12 deletions

View File

@ -15,9 +15,7 @@ NEDM is a modern, feature-rich Wayland compositor built on top of wlroots, evolv
### Desktop Integration
- **Wallpaper Support**: wallpaper with multiple scaling modes
- Fill, fit, stretch, center, and tile modes
- Configurable background colors
- **Wallpaper Support**: FOR NOW USE THIRD PARTY APP LIKE SWWW CURRENT SETUP IS BROKEN
- **Layer Shell Protocol**: Support for notification daemons and overlays
### Modern Wayland Features

View File

@ -26,6 +26,7 @@
#include "server.h"
#include "util.h"
#include "view.h"
#include "wallpaper.h"
#include "workspace.h"
char *keybinding_action_string[] = {FOREACH_KEYBINDING(GENERATE_STRING)};
@ -1951,7 +1952,7 @@ keybinding_configure_message(struct nedm_server *server,
void
keybinding_configure_wallpaper(struct nedm_server *server,
struct nedm_wallpaper_config *config) {
if(config->image_path != NULL) {
if(config->image_path != NULL && strcmp(config->image_path, "assets/nedm.png") != 0) {
free(server->wallpaper_config.image_path);
server->wallpaper_config.image_path = strdup(config->image_path);
}
@ -1960,6 +1961,10 @@ keybinding_configure_wallpaper(struct nedm_server *server,
server->wallpaper_config.bg_color[1] = config->bg_color[1];
server->wallpaper_config.bg_color[2] = config->bg_color[2];
server->wallpaper_config.bg_color[3] = config->bg_color[3];
// Refresh wallpapers on all outputs with new configuration
nedm_wallpaper_refresh_all_outputs(server);
ipc_send_event(server, "{\"event_name\":\"configure_wallpaper\"}");
}

View File

@ -63,6 +63,7 @@ cairo = dependency('cairo')
pango = dependency('pango')
pangocairo = dependency('pangocairo')
fontconfig = dependency('fontconfig')
gdkpixbuf = dependency('gdk-pixbuf-2.0')
libinput = dependency('libinput')
libevdev = dependency('libevdev')
libudev = dependency('libudev')
@ -201,6 +202,7 @@ nedm_dependencies_dict = {
'pango': [pango,true],
'cairo': [cairo,true],
'pangocairo': [pangocairo,true],
'gdkpixbuf': [gdkpixbuf,true],
'math': [math,true],
}
@ -218,6 +220,7 @@ reproducible_build_versions = {
'pango': '1.56.4',
'cairo': '1.18.4',
'pangocairo': '1.56.4',
'gdkpixbuf': '2.42.8',
'math': '-1'
}

View File

@ -17,6 +17,7 @@
#include <math.h>
#include <wlr/interfaces/wlr_buffer.h>
#include <drm_fourcc.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
struct wallpaper_buffer {
struct wlr_buffer base;
@ -146,20 +147,84 @@ bool nedm_wallpaper_load_image(struct nedm_wallpaper *wallpaper, const char *pat
return false;
}
// Load the image using Cairo
// First try to load as PNG directly for better performance
wallpaper->image_surface = cairo_image_surface_create_from_png(path);
if (cairo_surface_status(wallpaper->image_surface) != CAIRO_STATUS_SUCCESS) {
wlr_log(WLR_ERROR, "Failed to load wallpaper image: %s", path);
if (wallpaper->image_surface) {
cairo_surface_destroy(wallpaper->image_surface);
wallpaper->image_surface = NULL;
if (cairo_surface_status(wallpaper->image_surface) == CAIRO_STATUS_SUCCESS) {
// PNG loaded successfully
wallpaper->image_width = cairo_image_surface_get_width(wallpaper->image_surface);
wallpaper->image_height = cairo_image_surface_get_height(wallpaper->image_surface);
wlr_log(WLR_INFO, "Loaded PNG wallpaper: %s (%dx%d)", path,
wallpaper->image_width, wallpaper->image_height);
wallpaper->loaded = true;
return true;
}
// PNG failed, clean up and try with GdkPixbuf for other formats
if (wallpaper->image_surface) {
cairo_surface_destroy(wallpaper->image_surface);
wallpaper->image_surface = NULL;
}
GError *error = NULL;
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &error);
if (!pixbuf) {
wlr_log(WLR_ERROR, "Failed to load wallpaper image: %s - %s",
path, error ? error->message : "unknown error");
if (error) {
g_error_free(error);
}
return false;
}
// Get image dimensions
wallpaper->image_width = cairo_image_surface_get_width(wallpaper->image_surface);
wallpaper->image_height = cairo_image_surface_get_height(wallpaper->image_surface);
wallpaper->image_width = gdk_pixbuf_get_width(pixbuf);
wallpaper->image_height = gdk_pixbuf_get_height(pixbuf);
// Convert pixbuf to Cairo format
int channels = gdk_pixbuf_get_n_channels(pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
// Create Cairo surface
cairo_format_t format = channels >= 4 ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
wallpaper->image_surface = cairo_image_surface_create(format,
wallpaper->image_width, wallpaper->image_height);
if (cairo_surface_status(wallpaper->image_surface) != CAIRO_STATUS_SUCCESS) {
wlr_log(WLR_ERROR, "Failed to create Cairo surface for wallpaper");
g_object_unref(pixbuf);
return false;
}
cairo_surface_flush(wallpaper->image_surface);
unsigned char *cairo_data = cairo_image_surface_get_data(wallpaper->image_surface);
int cairo_stride = cairo_image_surface_get_stride(wallpaper->image_surface);
// Copy and convert pixel data
for (int y = 0; y < wallpaper->image_height; y++) {
guchar *src_row = pixels + y * rowstride;
unsigned char *dst_row = cairo_data + y * cairo_stride;
for (int x = 0; x < wallpaper->image_width; x++) {
if (channels >= 4) {
// RGBA to BGRA (Cairo uses BGRA internally)
dst_row[x * 4 + 0] = src_row[x * channels + 2]; // B
dst_row[x * 4 + 1] = src_row[x * channels + 1]; // G
dst_row[x * 4 + 2] = src_row[x * channels + 0]; // R
dst_row[x * 4 + 3] = src_row[x * channels + 3]; // A
} else {
// RGB to BGRx (Cairo uses BGRx for RGB24)
dst_row[x * 4 + 0] = src_row[x * channels + 2]; // B
dst_row[x * 4 + 1] = src_row[x * channels + 1]; // G
dst_row[x * 4 + 2] = src_row[x * channels + 0]; // R
dst_row[x * 4 + 3] = 0xFF; // Alpha = opaque
}
}
}
cairo_surface_mark_dirty(wallpaper->image_surface);
g_object_unref(pixbuf);
wlr_log(WLR_INFO, "Loaded wallpaper: %s (%dx%d)", path,
wallpaper->image_width, wallpaper->image_height);
@ -336,4 +401,18 @@ void nedm_wallpaper_init(struct nedm_server *server) {
(void)server;
// Wallpapers are created per-output, so nothing to initialize globally
wlr_log(WLR_INFO, "Wallpaper subsystem initialized");
}
void nedm_wallpaper_refresh_all_outputs(struct nedm_server *server) {
struct nedm_output *output;
wl_list_for_each(output, &server->outputs, link) {
if (output->wallpaper) {
// Destroy existing wallpaper
nedm_wallpaper_destroy(output->wallpaper);
output->wallpaper = NULL;
}
// Create new wallpaper with updated configuration
nedm_wallpaper_create_for_output(output);
}
wlr_log(WLR_INFO, "Refreshed wallpapers for all outputs");
}

View File

@ -51,5 +51,6 @@ void nedm_wallpaper_destroy(struct nedm_wallpaper *wallpaper);
void nedm_wallpaper_create_for_output(struct nedm_output *output);
void nedm_wallpaper_render(struct nedm_wallpaper *wallpaper);
bool nedm_wallpaper_load_image(struct nedm_wallpaper *wallpaper, const char *path);
void nedm_wallpaper_refresh_all_outputs(struct nedm_server *server);
#endif