xwm: Add icon support to the frame
This fetches the _NET_WM_ICON property of the X11 window, and use the first image found as the frame icon. This has been tested with various X11 programs, and improves usability and user-friendliness a bit. Changes since v1: - Changed frame_button_create() to use frame_button_create_from_surface() internally. - Removed a check that should never have been commited. Changes since v2: - Request UINT32_MAX items instead of 2048, to avoid cutting valid icons. - Strengthen checks against malformed input. - Handle XCB_PROPERTY_DELETE to remove the icon. - Schedule a repaint if the icon changed. Changes since v3: - Keep the previous Cairo surface until the new one has been successfully loaded. - Use uint32_t for cardinals. Unsigned is the same type except on 16-bit machines, but uint32_t is clearer. - Declare length as uint32_t too, like in xcb_get_property_reply_t. Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> Reviewed-by: Quentin Glidic <sardemff7+git@sardemff7.net>
This commit is contained in:
committed by
Daniel Stone
parent
cb04cc4f68
commit
6b58ea8c43
+1
-1
@@ -126,7 +126,7 @@ enum {
|
||||
|
||||
struct frame *
|
||||
frame_create(struct theme *t, int32_t width, int32_t height, uint32_t buttons,
|
||||
const char *title);
|
||||
const char *title, cairo_surface_t *icon);
|
||||
|
||||
void
|
||||
frame_destroy(struct frame *frame);
|
||||
|
||||
+40
-14
@@ -108,9 +108,9 @@ struct frame {
|
||||
};
|
||||
|
||||
static struct frame_button *
|
||||
frame_button_create(struct frame *frame, const char *icon,
|
||||
enum frame_status status_effect,
|
||||
enum frame_button_flags flags)
|
||||
frame_button_create_from_surface(struct frame *frame, cairo_surface_t *icon,
|
||||
enum frame_status status_effect,
|
||||
enum frame_button_flags flags)
|
||||
{
|
||||
struct frame_button *button;
|
||||
|
||||
@@ -118,12 +118,7 @@ frame_button_create(struct frame *frame, const char *icon,
|
||||
if (!button)
|
||||
return NULL;
|
||||
|
||||
button->icon = cairo_image_surface_create_from_png(icon);
|
||||
if (!button->icon) {
|
||||
free(button);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
button->icon = icon;
|
||||
button->frame = frame;
|
||||
button->flags = flags;
|
||||
button->status_effect = status_effect;
|
||||
@@ -133,6 +128,30 @@ frame_button_create(struct frame *frame, const char *icon,
|
||||
return button;
|
||||
}
|
||||
|
||||
static struct frame_button *
|
||||
frame_button_create(struct frame *frame, const char *icon_name,
|
||||
enum frame_status status_effect,
|
||||
enum frame_button_flags flags)
|
||||
{
|
||||
struct frame_button *button;
|
||||
cairo_surface_t *icon;
|
||||
|
||||
icon = cairo_image_surface_create_from_png(icon_name);
|
||||
if (cairo_surface_status(icon) != CAIRO_STATUS_SUCCESS)
|
||||
goto error;
|
||||
|
||||
button = frame_button_create_from_surface(frame, icon, status_effect,
|
||||
flags);
|
||||
if (!button)
|
||||
goto error;
|
||||
|
||||
return button;
|
||||
|
||||
error:
|
||||
cairo_surface_destroy(icon);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
frame_button_destroy(struct frame_button *button)
|
||||
{
|
||||
@@ -305,7 +324,7 @@ frame_destroy(struct frame *frame)
|
||||
|
||||
struct frame *
|
||||
frame_create(struct theme *t, int32_t width, int32_t height, uint32_t buttons,
|
||||
const char *title)
|
||||
const char *title, cairo_surface_t *icon)
|
||||
{
|
||||
struct frame *frame;
|
||||
struct frame_button *button;
|
||||
@@ -332,10 +351,17 @@ frame_create(struct theme *t, int32_t width, int32_t height, uint32_t buttons,
|
||||
}
|
||||
|
||||
if (title) {
|
||||
button = frame_button_create(frame,
|
||||
DATADIR "/weston/icon_window.png",
|
||||
FRAME_STATUS_MENU,
|
||||
FRAME_BUTTON_CLICK_DOWN);
|
||||
if (icon) {
|
||||
button = frame_button_create_from_surface(frame,
|
||||
icon,
|
||||
FRAME_STATUS_MENU,
|
||||
FRAME_BUTTON_CLICK_DOWN);
|
||||
} else {
|
||||
button = frame_button_create(frame,
|
||||
DATADIR "/weston/icon_window.png",
|
||||
FRAME_STATUS_MENU,
|
||||
FRAME_BUTTON_CLICK_DOWN);
|
||||
}
|
||||
if (!button)
|
||||
goto free_frame;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user