From 3db9f29453429eccc0db85a9eb318c2c27bee1c5 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Tue, 29 Jul 2008 16:51:21 +0200 Subject: [PATCH] appicon: new widget, used in titlebar Signed-off-by: Julien Danjou --- CMakeLists.txt | 3 +- lib/awful.lua.in | 3 +- statusbar.c | 2 +- structs.h | 2 +- titlebar.c | 3 +- widget.c | 9 ++-- widget.h | 3 +- widgets/appicon.c | 110 ++++++++++++++++++++++++++++++++++++++++++ widgets/graph.c | 5 +- widgets/progressbar.c | 4 +- widgets/systray.c | 3 +- widgets/taglist.c | 4 +- widgets/tasklist.c | 5 +- widgets/textbox.c | 4 +- 14 files changed, 144 insertions(+), 16 deletions(-) create mode 100644 widgets/appicon.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 72a7c22e..59a98367 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,8 @@ set(AWE_SRCS ${SOURCE_DIR}/widgets/taglist.c ${SOURCE_DIR}/widgets/tasklist.c ${SOURCE_DIR}/widgets/textbox.c - ${SOURCE_DIR}/widgets/systray.c) + ${SOURCE_DIR}/widgets/systray.c + ${SOURCE_DIR}/widgets/appicon.c) set(AWE_CLIENT_SRCS ${SOURCE_DIR}/awesome-client.c diff --git a/lib/awful.lua.in b/lib/awful.lua.in index b4a257be..39ed2f7e 100644 --- a/lib/awful.lua.in +++ b/lib/awful.lua.in @@ -847,8 +847,9 @@ end -- @return A brand new titlebar. function P.titlebar.new(args) local tb = titlebar(args) + tb:widget_add(widget({ type = "appicon", name = "appicon", align = "left" })) tb:widget_add(widget({ type = "textbox", name = "title" })) - local close_button= widget({ type = "textbox", name = "close", align = "right"}) + local close_button= widget({ type = "textbox", name = "close", align = "right" }) close_button:mouse_add(mouse({ }, 1, function (t) t:client_get():kill() end)) tb:widget_add(close_button) return tb diff --git a/statusbar.c b/statusbar.c index 36e36603..63cc0895 100644 --- a/statusbar.c +++ b/statusbar.c @@ -47,7 +47,7 @@ statusbar_draw(statusbar_t *statusbar) statusbar->sw->pixmap, statusbar->screen, statusbar->position, statusbar->sw->geometry.x, statusbar->sw->geometry.y, - statusbar); + statusbar, AWESOME_TYPE_STATUSBAR); simplewindow_refresh_pixmap(statusbar->sw); xcb_aux_sync(globalconf.connection); diff --git a/structs.h b/structs.h index c701eb82..e0e1a7d7 100644 --- a/structs.h +++ b/structs.h @@ -100,7 +100,7 @@ struct widget_t /** Widget detach function */ void (*detach)(widget_t *, void *); /** Draw function */ - int (*draw)(draw_context_t *, int, widget_node_t *, int, int, void *); + int (*draw)(draw_context_t *, int, widget_node_t *, int, int, void *, awesome_type_t); /** Index function */ int (*index)(lua_State *, awesome_token_t); /** Newindex function */ diff --git a/titlebar.c b/titlebar.c index 5b8a01bb..433007c8 100644 --- a/titlebar.c +++ b/titlebar.c @@ -113,7 +113,8 @@ titlebar_draw(client_t *c) widget_render(c->titlebar->widgets, ctx, c->titlebar->sw->gc, c->titlebar->sw->pixmap, c->screen, c->titlebar->position, - c->titlebar->sw->geometry.x, c->titlebar->sw->geometry.y, c->titlebar); + c->titlebar->sw->geometry.x, c->titlebar->sw->geometry.y, + c->titlebar, AWESOME_TYPE_TITLEBAR); switch(c->titlebar->position) { diff --git a/widget.c b/widget.c index 5b5f0242..8425b942 100644 --- a/widget.c +++ b/widget.c @@ -89,12 +89,13 @@ widget_common_button_press(widget_node_t *w, * \param y The y coordinates of the object. * pixmap when the object position is right or left. * \param object The object pointer. + * \param type The object type. * \todo Remove GC. */ void widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_pixmap_t rotate_px, int screen, position_t position, - int x, int y, void *object) + int x, int y, void *object, awesome_type_t type) { xcb_pixmap_t rootpix; xcb_screen_t *s; @@ -153,16 +154,16 @@ widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_gcontext_t gc, xcb_ for(w = wnode; w; w = w->next) if(w->widget->isvisible && w->widget->align == AlignLeft) - left += w->widget->draw(ctx, screen, w, left, (left + right), object); + left += w->widget->draw(ctx, screen, w, left, (left + right), object, type); /* renders right widget from last to first */ for(w = *widget_node_list_last(&wnode); w; w = w->prev) if(w->widget->isvisible && w->widget->align == AlignRight) - right += w->widget->draw(ctx, screen, w, right, (left + right), object); + right += w->widget->draw(ctx, screen, w, right, (left + right), object, type); for(w = wnode; w; w = w->next) if(w->widget->isvisible && w->widget->align == AlignFlex) - left += w->widget->draw(ctx, screen, w, left, (left + right), object); + left += w->widget->draw(ctx, screen, w, left, (left + right), object, type); switch(position) { diff --git a/widget.h b/widget.h index ca194708..8c9a0a22 100644 --- a/widget.h +++ b/widget.h @@ -31,7 +31,7 @@ void widget_invalidate_cache(int, int); int widget_calculate_offset(int, int, int, int); void widget_common_new(widget_t *); -void widget_render(widget_node_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, position_t, int, int, void *); +void widget_render(widget_node_t *, draw_context_t *, xcb_gcontext_t, xcb_drawable_t, int, position_t, int, int, void *, awesome_type_t); int luaA_widget_userdata_new(lua_State *, widget_t *); @@ -43,6 +43,7 @@ widget_constructor_t progressbar_new; widget_constructor_t graph_new; widget_constructor_t tasklist_new; widget_constructor_t systray_new; +widget_constructor_t appicon_new; #endif diff --git a/widgets/appicon.c b/widgets/appicon.c new file mode 100644 index 00000000..b5003027 --- /dev/null +++ b/widgets/appicon.c @@ -0,0 +1,110 @@ +/* + * appicon.c - application icon widget + * + * Copyright © 2008 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "widget.h" +#include "ewmh.h" +#include "titlebar.h" + +extern awesome_t globalconf; + +/** Draw a application icon widget. + * \param ctx The draw context. + * \param screen The screen. + * \param w The widget node we are linked from. + * \param offset Offset to draw at. + * \param used The size used on the element. + * \param p A pointer to the object we're draw onto. + * \param type The type of the object. + * \return The width used. + */ +static int +appicon_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), + widget_node_t *w, + int offset, int used, + void *p, awesome_type_t type) +{ + client_t *c = NULL; + netwm_icon_t *icon; + draw_image_t *image; + + switch(type) + { + case AWESOME_TYPE_STATUSBAR: + c = globalconf.focus->client; + break; + case AWESOME_TYPE_TITLEBAR: + c = client_getbytitlebar(p); + break; + } + + if(c) + { + if((image = draw_image_new(c->icon_path))) + { + w->area.width = ((double) ctx->height / (double) image->height) * image->width; + w->area.x = widget_calculate_offset(ctx->width, + w->area.width, + offset, + w->widget->align); + draw_image(ctx, w->area.x, + w->area.y, ctx->height, image); + draw_image_delete(&image); + } + else if((icon = ewmh_get_window_icon(c->win))) + { + w->area.width = ((double) ctx->height / (double) icon->height) + * icon->width; + w->area.x = widget_calculate_offset(ctx->width, + w->area.width, + offset, + w->widget->align); + draw_image_from_argb_data(ctx, + w->area.x, + w->area.y, + icon->width, icon->height, + ctx->height, icon->image); + netwm_icon_delete(&icon); + } + } + else + w->area.width = 0; + + return w->area.width; +} + +/** Create a new appicon widget. + * \param align Widget alignment. + * \return A brand new widget. + */ +widget_t * +appicon_new(alignment_t align) +{ + widget_t *w; + + w = p_new(widget_t, 1); + widget_common_new(w); + w->align = align; + w->draw = appicon_draw; + + return w; +} + +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/widgets/graph.c b/widgets/graph.c index 0b927def..54695e17 100644 --- a/widgets/graph.c +++ b/widgets/graph.c @@ -137,6 +137,8 @@ graph_plot_add(graph_data_t *d, const char *title) * \param offset The offset to draw at. * \param used The already used width. * \param p A pointer to the object we're drawing onto. + * \param type The object type. + * \return The widget width. */ static int graph_draw(draw_context_t *ctx, @@ -144,7 +146,8 @@ graph_draw(draw_context_t *ctx, widget_node_t *w, int offset, int used __attribute__ ((unused)), - void *p __attribute__ ((unused))) + void *p __attribute__ ((unused)), + awesome_type_t type) { int margin_top, y; graph_data_t *d = w->widget->data; diff --git a/widgets/progressbar.c b/widgets/progressbar.c index f3a23885..0d561faf 100644 --- a/widgets/progressbar.c +++ b/widgets/progressbar.c @@ -120,6 +120,7 @@ progressbar_bar_add(progressbar_data_t *d, const char *title) * \param offset Offset to draw at. * \param used Space already used. * \param object The object pointer we're drawing onto. + * \param type The object type. * \return The width used. */ static int @@ -128,7 +129,8 @@ progressbar_draw(draw_context_t *ctx, widget_node_t *w, int offset, int used __attribute__ ((unused)), - void *p __attribute__ ((unused))) + void *p __attribute__ ((unused)), + awesome_type_t type) { /* pb_.. values points to the widget inside a potential border */ int values_ticks, pb_x, pb_y, pb_height, pb_width, pb_progress, pb_offset; diff --git a/widgets/systray.c b/widgets/systray.c index b3f68d28..51e150e6 100644 --- a/widgets/systray.c +++ b/widgets/systray.c @@ -37,7 +37,8 @@ systray_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), widget_node_t *w, int offset, int used __attribute__ ((unused)), - void *p) + void *p, + awesome_type_t type) { int i = 0, phys_screen; xembed_window_t *em; diff --git a/widgets/taglist.c b/widgets/taglist.c index abf865a8..cecf43ec 100644 --- a/widgets/taglist.c +++ b/widgets/taglist.c @@ -76,13 +76,15 @@ taglist_drawn_area_getbyobj(taglist_drawn_area_t *list, void *p) * \param offset Offset to draw at. * \param used Space already used. * \param object The object pointer we're drawing onto. + * \param type The object type. * \return The width used. */ static int taglist_draw(draw_context_t *ctx, int screen, widget_node_t *w, int offset, int used __attribute__ ((unused)), - void *object) + void *object, + awesome_type_t type) { taglist_data_t *data = w->widget->data; area_t area; diff --git a/widgets/tasklist.c b/widgets/tasklist.c index 3086a284..61538207 100644 --- a/widgets/tasklist.c +++ b/widgets/tasklist.c @@ -105,11 +105,14 @@ tasklist_object_data_getbyobj(tasklist_object_data_t *od, void *p) * \param offset The offset to draw at. * \param used The already used width. * \param p A pointer to the object we're drawing onto. + * \param type The object type. + * \return The widget width. */ static int tasklist_draw(draw_context_t *ctx, int screen, widget_node_t *w, - int offset, int used, void *p) + int offset, int used, void *p, + awesome_type_t type) { client_t *c; tasklist_data_t *d = w->widget->data; diff --git a/widgets/textbox.c b/widgets/textbox.c index 0bb0085c..9596a4d2 100644 --- a/widgets/textbox.c +++ b/widgets/textbox.c @@ -42,13 +42,15 @@ typedef struct * \param offset Offset to draw at. * \param used The size used on the element. * \param p A pointer to the object we're draw onto. + * \param type The object type. * \return The width used. */ static int textbox_draw(draw_context_t *ctx, int screen __attribute__ ((unused)), widget_node_t *w, int offset, int used, - void *p __attribute__ ((unused))) + void *p __attribute__ ((unused)), + awesome_type_t type) { textbox_data_t *d = w->widget->data; draw_parser_data_t pdata, *pdata_arg = NULL;