can't figure out wallpaper issue, use SWWW for example instead
This commit is contained in:
parent
fb442ec54c
commit
ce8248db8a
|
@ -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
|
||||
|
|
|
@ -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\"}");
|
||||
}
|
||||
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
||||
|
|
95
wallpaper.c
95
wallpaper.c
|
@ -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");
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue