---
clients/window.c | 4 +--
libweston/compositor-wayland.c | 2 +-
shared/cairo-util.h | 2 +-
shared/frame.c | 54 +++++++++++++++++++++++++++----------
xwayland/window-manager.c | 61 ++++++++++++++++++++++++++++++++++++++++--
5 files changed, 103 insertions(+), 20 deletions(-)
diff --git a/clients/window.c b/clients/window.c
index 95796d46..15a86e15 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2546,7 +2546,7 @@ window_frame_create(struct window *window, void *data)
frame = xzalloc(sizeof *frame);
frame->frame = frame_create(window->display->theme, 0, 0,
- buttons, window->title);
+ buttons, window->title, NULL);
frame->widget = window_add_widget(window, frame);
frame->child = widget_add_widget(frame->widget, data);
@@ -5449,7 +5449,7 @@ create_menu(struct display *display,
menu->user_data = user_data;
menu->widget = window_add_widget(menu->window, menu);
menu->frame = frame_create(window->display->theme, 0, 0,
- FRAME_BUTTON_NONE, NULL);
+ FRAME_BUTTON_NONE, NULL, NULL);
fail_on_null(menu->frame, 0, __FILE__, __LINE__);
menu->entries = entries;
menu->count = count;
diff --git a/libweston/compositor-wayland.c b/libweston/compositor-wayland.c
index 14f2c8db..aa6e5043 100644
--- a/libweston/compositor-wayland.c
+++ b/libweston/compositor-wayland.c
@@ -862,7 +862,7 @@ wayland_output_set_windowed(struct wayland_output *output)
return -1;
}
output->frame = frame_create(b->theme, 100, 100,
- FRAME_BUTTON_CLOSE, output->title);
+ FRAME_BUTTON_CLOSE, output->title, NULL);
if (!output->frame)
return -1;
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 84cf005e..7893ca24 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -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);
diff --git a/shared/frame.c b/shared/frame.c
index eb0cd77a..32779856 100644
--- a/shared/frame.c
+++ b/shared/frame.c
@@ -106,9 +106,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;
@@ -116,12 +116,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;
@@ -131,6 +126,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)
{
@@ -303,7 +322,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;
@@ -330,10 +349,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;
}
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index d40d56ea..e10db47c 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -138,6 +138,8 @@ struct weston_wm_window {
xcb_window_t frame_id;
struct frame *frame;
cairo_surface_t *cairo_surface;
+ int icon;
+ cairo_surface_t *icon_surface;
uint32_t surface_id;
struct weston_surface *surface;
struct weston_desktop_xwayland_surface *shsurf;
@@ -471,6 +473,7 @@ weston_wm_window_read_properties(struct weston_wm_window
*window)
{ wm->atom.net_wm_state, TYPE_NET_WM_STATE, NULL
},
{ wm->atom.net_wm_window_type, XCB_ATOM_ATOM,
F(type) },
{ wm->atom.net_wm_name, XCB_ATOM_STRING,
F(name) },
+ { wm->atom.net_wm_icon, XCB_ATOM_CARDINAL,
F(icon) },
{ wm->atom.net_wm_pid, XCB_ATOM_CARDINAL,
F(pid) },
{ wm->atom.motif_wm_hints, TYPE_MOTIF_WM_HINTS, NULL
},
{ wm->atom.wm_client_machine, XCB_ATOM_WM_CLIENT_MACHINE,
F(machine) },
@@ -931,8 +934,9 @@ weston_wm_window_create_frame(struct weston_wm_window
*window)
buttons |= FRAME_BUTTON_MAXIMIZE;
window->frame = frame_create(window->wm->theme,
- window->width, window->height,
- buttons, window->name);
+ window->width, window->height,
+ buttons, window->name,
+ window->icon_surface);
frame_resize_inside(window->frame, window->width, window->height);
weston_wm_window_get_frame_size(window, &width, &height);
@@ -1271,6 +1275,49 @@ weston_wm_window_schedule_repaint(struct
weston_wm_window *window)
}
static void
+weston_wm_handle_icon(struct weston_wm *wm, struct weston_wm_window *window)
+{
+ xcb_get_property_reply_t *reply;
+ xcb_get_property_cookie_t cookie;
+ int length;
+ unsigned *data, width, height;