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
|
### Desktop Integration
|
||||||
|
|
||||||
- **Wallpaper Support**: wallpaper with multiple scaling modes
|
- **Wallpaper Support**: FOR NOW USE THIRD PARTY APP LIKE SWWW CURRENT SETUP IS BROKEN
|
||||||
- Fill, fit, stretch, center, and tile modes
|
|
||||||
- Configurable background colors
|
|
||||||
- **Layer Shell Protocol**: Support for notification daemons and overlays
|
- **Layer Shell Protocol**: Support for notification daemons and overlays
|
||||||
|
|
||||||
### Modern Wayland Features
|
### Modern Wayland Features
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
#include "wallpaper.h"
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
|
|
||||||
char *keybinding_action_string[] = {FOREACH_KEYBINDING(GENERATE_STRING)};
|
char *keybinding_action_string[] = {FOREACH_KEYBINDING(GENERATE_STRING)};
|
||||||
|
@ -1951,7 +1952,7 @@ keybinding_configure_message(struct nedm_server *server,
|
||||||
void
|
void
|
||||||
keybinding_configure_wallpaper(struct nedm_server *server,
|
keybinding_configure_wallpaper(struct nedm_server *server,
|
||||||
struct nedm_wallpaper_config *config) {
|
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);
|
free(server->wallpaper_config.image_path);
|
||||||
server->wallpaper_config.image_path = strdup(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[1] = config->bg_color[1];
|
||||||
server->wallpaper_config.bg_color[2] = config->bg_color[2];
|
server->wallpaper_config.bg_color[2] = config->bg_color[2];
|
||||||
server->wallpaper_config.bg_color[3] = config->bg_color[3];
|
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\"}");
|
ipc_send_event(server, "{\"event_name\":\"configure_wallpaper\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ cairo = dependency('cairo')
|
||||||
pango = dependency('pango')
|
pango = dependency('pango')
|
||||||
pangocairo = dependency('pangocairo')
|
pangocairo = dependency('pangocairo')
|
||||||
fontconfig = dependency('fontconfig')
|
fontconfig = dependency('fontconfig')
|
||||||
|
gdkpixbuf = dependency('gdk-pixbuf-2.0')
|
||||||
libinput = dependency('libinput')
|
libinput = dependency('libinput')
|
||||||
libevdev = dependency('libevdev')
|
libevdev = dependency('libevdev')
|
||||||
libudev = dependency('libudev')
|
libudev = dependency('libudev')
|
||||||
|
@ -201,6 +202,7 @@ nedm_dependencies_dict = {
|
||||||
'pango': [pango,true],
|
'pango': [pango,true],
|
||||||
'cairo': [cairo,true],
|
'cairo': [cairo,true],
|
||||||
'pangocairo': [pangocairo,true],
|
'pangocairo': [pangocairo,true],
|
||||||
|
'gdkpixbuf': [gdkpixbuf,true],
|
||||||
'math': [math,true],
|
'math': [math,true],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +220,7 @@ reproducible_build_versions = {
|
||||||
'pango': '1.56.4',
|
'pango': '1.56.4',
|
||||||
'cairo': '1.18.4',
|
'cairo': '1.18.4',
|
||||||
'pangocairo': '1.56.4',
|
'pangocairo': '1.56.4',
|
||||||
|
'gdkpixbuf': '2.42.8',
|
||||||
'math': '-1'
|
'math': '-1'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
95
wallpaper.c
95
wallpaper.c
|
@ -17,6 +17,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <wlr/interfaces/wlr_buffer.h>
|
#include <wlr/interfaces/wlr_buffer.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
|
||||||
struct wallpaper_buffer {
|
struct wallpaper_buffer {
|
||||||
struct wlr_buffer base;
|
struct wlr_buffer base;
|
||||||
|
@ -146,20 +147,84 @@ bool nedm_wallpaper_load_image(struct nedm_wallpaper *wallpaper, const char *pat
|
||||||
return false;
|
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);
|
wallpaper->image_surface = cairo_image_surface_create_from_png(path);
|
||||||
if (cairo_surface_status(wallpaper->image_surface) != CAIRO_STATUS_SUCCESS) {
|
if (cairo_surface_status(wallpaper->image_surface) == CAIRO_STATUS_SUCCESS) {
|
||||||
wlr_log(WLR_ERROR, "Failed to load wallpaper image: %s", path);
|
// PNG loaded successfully
|
||||||
if (wallpaper->image_surface) {
|
wallpaper->image_width = cairo_image_surface_get_width(wallpaper->image_surface);
|
||||||
cairo_surface_destroy(wallpaper->image_surface);
|
wallpaper->image_height = cairo_image_surface_get_height(wallpaper->image_surface);
|
||||||
wallpaper->image_surface = NULL;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get image dimensions
|
// Get image dimensions
|
||||||
wallpaper->image_width = cairo_image_surface_get_width(wallpaper->image_surface);
|
wallpaper->image_width = gdk_pixbuf_get_width(pixbuf);
|
||||||
wallpaper->image_height = cairo_image_surface_get_height(wallpaper->image_surface);
|
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,
|
wlr_log(WLR_INFO, "Loaded wallpaper: %s (%dx%d)", path,
|
||||||
wallpaper->image_width, wallpaper->image_height);
|
wallpaper->image_width, wallpaper->image_height);
|
||||||
|
@ -336,4 +401,18 @@ void nedm_wallpaper_init(struct nedm_server *server) {
|
||||||
(void)server;
|
(void)server;
|
||||||
// Wallpapers are created per-output, so nothing to initialize globally
|
// Wallpapers are created per-output, so nothing to initialize globally
|
||||||
wlr_log(WLR_INFO, "Wallpaper subsystem initialized");
|
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_create_for_output(struct nedm_output *output);
|
||||||
void nedm_wallpaper_render(struct nedm_wallpaper *wallpaper);
|
void nedm_wallpaper_render(struct nedm_wallpaper *wallpaper);
|
||||||
bool nedm_wallpaper_load_image(struct nedm_wallpaper *wallpaper, const char *path);
|
bool nedm_wallpaper_load_image(struct nedm_wallpaper *wallpaper, const char *path);
|
||||||
|
void nedm_wallpaper_refresh_all_outputs(struct nedm_server *server);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue