diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3bc50557..494d2cf1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,7 +64,6 @@ set(AWE_SRCS
${SOURCE_DIR}/swindow.c
${SOURCE_DIR}/common/buffer.c
${SOURCE_DIR}/common/atoms.c
- ${SOURCE_DIR}/common/markup.c
${SOURCE_DIR}/common/socket.c
${SOURCE_DIR}/common/util.c
${SOURCE_DIR}/common/version.c
diff --git a/README b/README
index 80e0e519..176ca1b7 100644
--- a/README
+++ b/README
@@ -14,7 +14,6 @@ In order to build awesome itself, you need header files and libs of:
- cairo built with xcb support
- pango and pangocairo
- libev
- - glib
- Imlib2
- dbus (optional, use -DWITH_DBUS=OFF with cmake to disable)
- gperf
diff --git a/awesomerc.5.txt b/awesomerc.5.txt
index c4efa93c..8b8a83aa 100644
--- a/awesomerc.5.txt
+++ b/awesomerc.5.txt
@@ -37,22 +37,13 @@ alpha channel to `aa' and will blend the green with the color under it.
TEXT FORMAT
-----------
-You can use and mix Pango markup and awesome markup in text string.
+You can use Pango markup in text string.
This allows to format the text rendered in widgets.
Pango markup documentation can be found in the Pango documentation at
http://library.gnome.org/devel/pango/stable/PangoMarkupFormat.html.
-List of *awesome* markup elements and their attributes:
-
-* bg
- - image: path to a background image
- - align: background image alignment
- - resize: resize background image to text size
-
A Pango markup example: ....
-An *awesome* markup example: .
-
SEE ALSO
--------
awesome(1) awesome-client(1)
diff --git a/awesomerc.lua.in b/awesomerc.lua.in
index b3958e9b..4af90573 100644
--- a/awesomerc.lua.in
+++ b/awesomerc.lua.in
@@ -104,7 +104,7 @@ mymainmenu = awful.menu.new({ items = { { "awesome", myawesomemenu, beautiful.aw
}
})
-mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
+mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
menu = mymainmenu })
-- Create a systray
diff --git a/client.c b/client.c
index 97624438..23e0a6c3 100644
--- a/client.c
+++ b/client.c
@@ -30,7 +30,6 @@
#include "systray.h"
#include "property.h"
#include "wibox.h"
-#include "common/markup.h"
#include "common/atoms.h"
extern awesome_t globalconf;
diff --git a/common/markup.c b/common/markup.c
deleted file mode 100644
index 6de94d7f..00000000
--- a/common/markup.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * markup.c - markup functions
- *
- * 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
-
-#include "common/markup.h"
-
-/** Callback to invoke when the opening tag of an element is seen.
- * Here is just copies element elements we do not care about, and copies
- * values we care.
- * \param context the context of GMarkup
- * \param element_name element name
- * \param attribute_names array of attribute names
- * \param attribute_values array of attribute values
- * \param user_data pointer to user data, here a markup_parser_data_t pointer
- * \param error a GError
- */
-static void
-markup_parse_start_element(GMarkupParseContext *context __attribute__ ((unused)),
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error __attribute__ ((unused)))
-{
- markup_parser_data_t *p = (markup_parser_data_t *) user_data;
- int i;
-
- for(i = 0; p->elements[i]; i++)
- if(!a_strcmp(element_name, p->elements[i])) {
- (*p->on_element)(p, element_name, attribute_names,
- attribute_values);
- return;
- }
-
- if(a_strcmp(element_name, "markup"))
- {
- buffer_addf(&p->text, "<%s", element_name);
- for(i = 0; attribute_names[i]; i++)
- {
- buffer_addf(&p->text, " %s=\"%s\"", attribute_names[i],
- attribute_values[i]);
- }
- buffer_addc(&p->text, '>');
- }
-}
-
-/** Callback to invoke when the closing tag of an element is seen. Note that
- * this is also called for empty tags like \.
- * Here is just copies element elements we do not care about.
- * \param context the context of GMarkup
- * \param element_name element name
- * \param user_data pointer to user data, here a markup_parser_data_t pointer
- * \param error a GError
- */
-static void
-markup_parse_end_element(GMarkupParseContext *context __attribute__ ((unused)),
- const gchar *element_name,
- gpointer user_data,
- GError **error __attribute__ ((unused)))
-{
- markup_parser_data_t *p = (markup_parser_data_t *) user_data;
- int i;
-
- for(i = 0; p->elements[i]; i++)
- if(!a_strcmp(element_name, p->elements[i]))
- return;
-
- if(a_strcmp(element_name, "markup"))
- buffer_addf(&p->text, "%s>", element_name);
-}
-
-/** Callback to invoke when some text is seen (text is always inside an
- * element). Note that the text of an element may be spread over multiple calls
- * of this function. If the G_MARKUP_TREAT_CDATA_AS_TEXT flag is set, this
- * function is also called for the content of CDATA marked sections.
- * Here it recopies blindly the text in the text attribute of user_data.
- * \param context the context of GMarkup
- * \param text the text
- * \param text_len the text length
- * \param user_data pointer to user data, here a markup_parser_data_t pointer
- * \param error a GError
- */
-static void
-markup_parse_text(GMarkupParseContext *context __attribute__ ((unused)),
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **error __attribute__ ((unused)))
-{
- markup_parser_data_t *p = (markup_parser_data_t *) user_data;
-
- if (text_len) {
- buffer_grow(&p->text, text_len);
- buffer_add_xmlescaped(&p->text, text);
- }
-}
-
-/** Create a markup_parser_data_t structure with elements list.
- * \param a pointer to an allocated markup_parser_data_t which must be wiped
- * with markup_parser_data_wipe()
- */
-void markup_parser_data_init(markup_parser_data_t *p)
-{
- buffer_init(&p->text);
-}
-
-/** Wipe a markup_parser_data_t initialized with markup_parser_data_init.
- * \param p markup_parser_data_t address
- */
-void
-markup_parser_data_wipe(markup_parser_data_t *p)
-{
- buffer_wipe(&p->text);
-}
-
-/** Parse markup defined in data on the string str.
- * \param data A markup_parser_data_t allocated by markup_parser_data_new().
- * \param str A string to parse markup from.
- * \param slen String length.
- * \return True if success, false otherwise.
- */
-bool
-markup_parse(markup_parser_data_t *data, const char *str, ssize_t slen)
-{
- static GMarkupParser const parser =
- {
- /* start_element */
- markup_parse_start_element,
- /* end_element */
- markup_parse_end_element,
- /* text */
- markup_parse_text,
- /* passthrough */
- NULL,
- /* error */
- NULL
- };
- GMarkupParseContext *mkp_ctx;
- GError *error = NULL;
-
- if(slen <= 0)
- return false;
-
- mkp_ctx = g_markup_parse_context_new(&parser, 0, data, NULL);
-
- if(!g_markup_parse_context_parse(mkp_ctx, "", -1, &error)
- || !g_markup_parse_context_parse(mkp_ctx, str, slen, &error)
- || !g_markup_parse_context_parse(mkp_ctx, "", -1, &error)
- || !g_markup_parse_context_end_parse(mkp_ctx, &error))
- {
- warn("unable to parse text \"%s\": %s", str, error ? error->message : "unknown error");
- if(error)
- g_error_free(error);
- g_markup_parse_context_free(mkp_ctx);
- return false;
- }
-
- g_markup_parse_context_free(mkp_ctx);
-
- return true;
-}
-
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
diff --git a/common/markup.h b/common/markup.h
deleted file mode 100644
index e14d30c9..00000000
--- a/common/markup.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * markup.h - markup header
- *
- * 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.
- *
- */
-
-#ifndef AWESOME_COMMON_MARKUP_H
-#define AWESOME_COMMON_MARKUP_H
-
-#include "common/buffer.h"
-
-typedef struct markup_parser_data_t markup_parser_data_t;
-
-typedef void (markup_on_elem_f)(markup_parser_data_t *, const char *,
- const char **, const char **);
-
-struct markup_parser_data_t
-{
- buffer_t text;
- const char * const *elements;
- markup_on_elem_f *on_element;
- void *priv;
-};
-
-void markup_parser_data_init(markup_parser_data_t *);
-void markup_parser_data_wipe(markup_parser_data_t *);
-bool markup_parse(markup_parser_data_t *data, const char *, ssize_t);
-
-#endif
-// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
diff --git a/common/tokenize.gperf b/common/tokenize.gperf
index 03e161ea..d168737e 100644
--- a/common/tokenize.gperf
+++ b/common/tokenize.gperf
@@ -1,8 +1,10 @@
-1
align
bar_data_add
bar_properties_set
bg
+bg_align
+bg_image
+bg_resize
border_color
border_padding
border_width
@@ -57,7 +59,6 @@ Mod5
mouse_enter
mouse_leave
name
-on
ontop
opacity
orientation
@@ -84,7 +85,6 @@ ticks_gap
titlebar
top
transient_for
-true
type
urgent
valign
@@ -96,4 +96,3 @@ word
word_char
workarea
wrap
-yes
diff --git a/common/util.h b/common/util.h
index b0616909..483c0969 100644
--- a/common/util.h
+++ b/common/util.h
@@ -37,8 +37,6 @@
#include
#endif
-#include "tokenize.h"
-
typedef enum
{
East,
@@ -313,29 +311,6 @@ a_strncat(char *dst, ssize_t n, const char *src, ssize_t l)
return dlen + a_strncpy(dst + dlen, n - dlen, src, l);
}
-/** \brief convert a string to a boolean value.
- *
- * The a_strtobool() function converts a string \c s into a boolean.
- * It recognizes the strings "true", "on", "yes" and "1".
- *
- * \param[in] s the string to convert
- * \return true if the string is recognized as possibly true, false otherwise.
- */
-static inline bool
-a_strtobool(const char *s, ssize_t len)
-{
- switch(a_tokenize(s, len))
- {
- case A_TK_TRUE:
- case A_TK_YES:
- case A_TK_ON:
- case A_TK_1:
- return true;
- default:
- return false;
- }
-}
-
#define fatal(string, ...) _fatal(__LINE__, \
__FUNCTION__, \
string, ## __VA_ARGS__)
diff --git a/common/xutil.c b/common/xutil.c
index c46f73f0..4d947ebb 100644
--- a/common/xutil.c
+++ b/common/xutil.c
@@ -27,6 +27,7 @@
#include "common/xutil.h"
#include "common/atoms.h"
+#include "common/tokenize.h"
/** Get the string value of an atom.
* \param conn X connection.
diff --git a/draw.c b/draw.c
index 7e3aff4f..4790b113 100644
--- a/draw.c
+++ b/draw.c
@@ -32,7 +32,6 @@
#include "structs.h"
#include "common/tokenize.h"
-#include "common/markup.h"
extern awesome_t globalconf;
@@ -159,81 +158,28 @@ draw_font_delete(font_t **font)
}
}
-static void
-draw_markup_on_element(markup_parser_data_t *p, const char *elem,
- const char **names, const char **values)
+/** Initialize a draw_text_context_t with text data.
+ * \param data The draw text context to init.
+ * \param str The text string to render.
+ * \param slen The text string length.
+ * \return True if everything is ok, false otherwise.
+ */
+bool
+draw_text_context_init(draw_text_context_t *data, const char *str, ssize_t slen)
{
- draw_parser_data_t *data = p->priv;
-
- /* hack: markup.c validates tags so we can avoid strcmps here */
- switch (*elem) {
- case 'b':
- if(elem[2] == '_') /* bg_margin */
- for(; *names; names++, values++)
- switch(a_tokenize(*names, -1))
- {
- case A_TK_LEFT:
- data->bg_margin.left = atoi(*values);
- break;
- case A_TK_TOP:
- data->bg_margin.top = atoi(*values);
- default:
- break;
- }
- else /* bg */
- for(; *names; names++, values++)
- switch(a_tokenize(*names, -1))
- {
- case A_TK_IMAGE:
- if(data->bg_image)
- image_delete(&data->bg_image);
- data->bg_image = image_new_from_file(*values);
- break;
- case A_TK_ALIGN:
- data->bg_align = draw_align_fromstr(*values, -1);
- break;
- case A_TK_RESIZE:
- data->bg_resize = a_strtobool(*values, -1);
- default:
- break;
- }
- break;
- }
-}
-
-static bool
-draw_text_markup_expand(draw_parser_data_t *data,
- const char *str, ssize_t slen)
-{
- static char const * const elements[] = { "bg", "bg_margin", NULL };
- markup_parser_data_t p =
- {
- .elements = elements,
- .priv = data,
- .on_element = &draw_markup_on_element,
- };
GError *error = NULL;
- bool ret = false;
- markup_parser_data_init(&p);
-
- if(!markup_parse(&p, str, slen))
- goto bailout;
-
- if(!pango_parse_markup(p.text.s, p.text.len, 0, &data->attr_list, &data->text, NULL, &error))
+ if(!pango_parse_markup(str, slen, 0, &data->attr_list, &data->text, NULL, &error))
{
warn("cannot parse pango markup: %s", error ? error->message : "unknown error");
if(error)
g_error_free(error);
- goto bailout;
+ return false;
}
data->len = a_strlen(data->text);
- ret = true;
- bailout:
- markup_parser_data_wipe(&p);
- return ret;
+ return true;
}
/** Initialize a new draw context.
@@ -273,57 +219,17 @@ draw_context_init(draw_context_t *d, int phys_screen,
* \param align Text alignment.
* \param margin Margin to respect when drawing text.
* \param area Area to draw to.
- * \param text Text to draw.
- * \param len Text to draw length.
- * \param data Optional parser data.
+ * \param data Draw text context data.
* \param ext Text extents.
*/
void
-draw_text(draw_context_t *ctx, font_t *font, PangoEllipsizeMode ellip, PangoWrapMode wrap,
- alignment_t align, padding_t *margin, area_t area, const char *text, ssize_t len,
- draw_parser_data_t *pdata, area_t *ext)
+draw_text(draw_context_t *ctx, draw_text_context_t *data, font_t *font,
+ PangoEllipsizeMode ellip, PangoWrapMode wrap,
+ alignment_t align, padding_t *margin, area_t area, area_t *ext)
{
int x, y;
- draw_parser_data_t parser_data;
- if(!pdata)
- {
- draw_parser_data_init(&parser_data);
- if(draw_text_markup_expand(&parser_data, text, len))
- {
- text = parser_data.text;
- len = parser_data.len;
- }
- pdata = &parser_data;
- }
- else
- {
- text = pdata->text;
- len = pdata->len;
- }
-
- if(pdata->bg_image)
- {
- x = area.x;
- y = area.y;
- switch(pdata->bg_align)
- {
- case AlignCenter:
- x += (area.width - pdata->bg_image->width) / 2;
- break;
- case AlignRight:
- x += area.width- pdata->bg_image->width;
- break;
- default:
- break;
- }
- draw_image(ctx,
- x + pdata->bg_margin.left,
- y + pdata->bg_margin.top,
- pdata->bg_resize ? area.height : 0, pdata->bg_image);
- }
-
- pango_layout_set_text(ctx->layout, pdata->text, pdata->len);
+ pango_layout_set_text(ctx->layout, data->text, data->len);
pango_layout_set_width(ctx->layout,
pango_units_from_double(area.width
- (margin->left
@@ -332,7 +238,7 @@ draw_text(draw_context_t *ctx, font_t *font, PangoEllipsizeMode ellip, PangoWrap
- (margin->top + margin->bottom));
pango_layout_set_ellipsize(ctx->layout, ellip);
pango_layout_set_wrap(ctx->layout, wrap);
- pango_layout_set_attributes(ctx->layout, pdata->attr_list);
+ pango_layout_set_attributes(ctx->layout, data->attr_list);
pango_layout_set_font_description(ctx->layout, font->desc);
x = area.x + margin->left;
@@ -364,9 +270,6 @@ draw_text(draw_context_t *ctx, font_t *font, PangoEllipsizeMode ellip, PangoWrap
ctx->fg.alpha / 65535.0);
pango_cairo_update_layout(ctx->cr, ctx->layout);
pango_cairo_show_layout(ctx->cr, ctx->layout);
-
- if (pdata == &parser_data)
- draw_parser_data_wipe(&parser_data);
}
/** Setup color-source for cairo (gradient or mono).
@@ -657,14 +560,13 @@ draw_graph_line(draw_context_t *ctx, area_t rect, int *to, int cur_index,
* \param y Y coordinate.
* \param w Width.
* \param h Height.
- * \param wanted_h Wanted height: if > 0, image will be resized.
+ * \param ratio The ratio to apply to the image.
* \param data The image pixels array.
*/
static void
draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h,
- int wanted_h, unsigned char *data)
+ double ratio, unsigned char *data)
{
- double ratio;
cairo_t *cr;
cairo_surface_t *source;
@@ -675,14 +577,8 @@ draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h,
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w));
#endif
cr = cairo_create(ctx->surface);
- if(wanted_h > 0 && h > 0)
- {
- ratio = (double) wanted_h / (double) h;
- cairo_scale(cr, ratio, ratio);
- cairo_set_source_surface(cr, source, x / ratio, y / ratio);
- }
- else
- cairo_set_source_surface(cr, source, x, y);
+ cairo_scale(cr, ratio, ratio);
+ cairo_set_source_surface(cr, source, x / ratio, y / ratio);
cairo_paint(cr);
@@ -694,13 +590,13 @@ draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h,
* \param ctx Draw context to draw to.
* \param x X coordinate.
* \param y Y coordinate.
- * \param wanted_h Wanted height: if > 0, image will be resized.
+ * \param ratio The ratio to apply to the image.
* \param image The image to draw.
*/
void
-draw_image(draw_context_t *ctx, int x, int y, int wanted_h, image_t *image)
+draw_image(draw_context_t *ctx, int x, int y, double ratio, image_t *image)
{
- draw_image_from_argb_data(ctx, x, y, image->width, image->height, wanted_h, image->data);
+ draw_image_from_argb_data(ctx, x, y, image->width, image->height, ratio, image->data);
}
/** Rotate a pixmap.
@@ -743,14 +639,12 @@ draw_rotate(draw_context_t *ctx,
}
/** Return the width and height of a text in pixel.
+ * \param data The draw context text data.
* \param font Font to use.
- * \param text The text.
- * \param len The text length.
- * \param pdata The parser data to fill.
* \return Text height and width.
*/
area_t
-draw_text_extents(font_t *font, const char *text, ssize_t len, draw_parser_data_t *parser_data)
+draw_text_extents(draw_text_context_t *data, font_t *font)
{
cairo_surface_t *surface;
cairo_t *cr;
@@ -759,10 +653,7 @@ draw_text_extents(font_t *font, const char *text, ssize_t len, draw_parser_data_
xcb_screen_t *s = xutil_screen_get(globalconf.connection, globalconf.default_screen);
area_t geom = { 0, 0, 0, 0 };
- if(!len)
- return geom;
-
- if(!draw_text_markup_expand(parser_data, text, len))
+ if(data->len <= 0)
return geom;
surface = cairo_xcb_surface_create(globalconf.connection,
@@ -773,8 +664,8 @@ draw_text_extents(font_t *font, const char *text, ssize_t len, draw_parser_data_
cr = cairo_create(surface);
layout = pango_cairo_create_layout(cr);
- pango_layout_set_text(layout, parser_data->text, parser_data->len);
- pango_layout_set_attributes(layout, parser_data->attr_list);
+ pango_layout_set_text(layout, data->text, data->len);
+ pango_layout_set_attributes(layout, data->attr_list);
pango_layout_set_font_description(layout, font->desc);
pango_layout_get_pixel_extents(layout, NULL, &ext);
g_object_unref(layout);
diff --git a/draw.h b/draw.h
index 89c3ce25..ee628f13 100644
--- a/draw.h
+++ b/draw.h
@@ -169,16 +169,10 @@ typedef struct
PangoAttrList *attr_list;
char *text;
ssize_t len;
- struct
- {
- int top, left;
- } bg_margin;
- image_t *bg_image;
- alignment_t bg_align;
- bool bg_resize;
-} draw_parser_data_t;
+} draw_text_context_t;
-void draw_text(draw_context_t *, font_t *, PangoEllipsizeMode, PangoWrapMode, alignment_t, padding_t *, area_t, const char *, ssize_t len, draw_parser_data_t *, area_t *);
+bool draw_text_context_init(draw_text_context_t *, const char *, ssize_t);
+void draw_text(draw_context_t *, draw_text_context_t *, font_t *, PangoEllipsizeMode, PangoWrapMode, alignment_t, padding_t *, area_t, area_t *);
void draw_rectangle(draw_context_t *, area_t, float, bool, const xcolor_t *);
void draw_rectangle_gradient(draw_context_t *, area_t, float, bool, vector_t,
const xcolor_t *, const xcolor_t *, const xcolor_t *);
@@ -188,9 +182,9 @@ void draw_graph(draw_context_t *, area_t, int *, int *, int, position_t, vector_
const xcolor_t *, const xcolor_t *, const xcolor_t *);
void draw_graph_line(draw_context_t *, area_t, int *, int, position_t, vector_t,
const xcolor_t *, const xcolor_t *, const xcolor_t *);
-void draw_image(draw_context_t *, int, int, int, image_t *);
+void draw_image(draw_context_t *, int, int, double, image_t *);
void draw_rotate(draw_context_t *, xcb_drawable_t, xcb_drawable_t, int, int, int, int, double, int, int);
-area_t draw_text_extents(font_t *, const char *, ssize_t, draw_parser_data_t *);
+area_t draw_text_extents(draw_text_context_t *, font_t *);
alignment_t draw_align_fromstr(const char *, ssize_t);
const char *draw_align_tostr(alignment_t);
@@ -212,19 +206,13 @@ xcolor_init_request_t xcolor_init_unchecked(xcolor_t *, const char *, ssize_t);
bool xcolor_init_reply(xcolor_init_request_t);
static inline void
-draw_parser_data_init(draw_parser_data_t *pdata)
-{
- p_clear(pdata, 1);
-}
-
-static inline void
-draw_parser_data_wipe(draw_parser_data_t *pdata)
+draw_text_context_wipe(draw_text_context_t *pdata)
{
if(pdata)
{
- pango_attr_list_unref(pdata->attr_list);
+ if(pdata->attr_list)
+ pango_attr_list_unref(pdata->attr_list);
p_delete(&pdata->text);
- image_unref(&pdata->bg_image);
}
}
diff --git a/lib/awful/titlebar.lua.in b/lib/awful/titlebar.lua.in
index 6d860188..bfacf4f4 100644
--- a/lib/awful/titlebar.lua.in
+++ b/lib/awful/titlebar.lua.in
@@ -6,6 +6,7 @@
-- Grab environment we need
local math = math
+local image = image
local pairs = pairs
local otable = otable
local capi =
@@ -72,13 +73,13 @@ function add(c, args)
local closef
if theme.titlebar_close_button_focus then
closef = widget.button({ align = "right",
- image = theme.titlebar_close_button_focus })
+ image = image(theme.titlebar_close_button_focus) })
end
local close
if theme.titlebar_close_button_normal then
close = widget.button({ align = "right",
- image = theme.titlebar_close_button_normal })
+ image = image(theme.titlebar_close_button_normal) })
end
if close or closef then
diff --git a/lib/awful/widget.lua.in b/lib/awful/widget.lua.in
index 8d82e847..ecc666ee 100644
--- a/lib/awful/widget.lua.in
+++ b/lib/awful/widget.lua.in
@@ -15,6 +15,7 @@ local capi =
client = client,
button = button,
widget = widget,
+ image = image,
mouse = mouse
}
local util = require("awful.util")
@@ -51,20 +52,24 @@ local function taglist_update (screen, w, label, buttons, data)
end
-- Update widgets text
for k, tag in ipairs(tags) do
- w[k].text, w[k].bg = label(tag)
- if buttons then
- if not data[tag] then
- -- Replace press function by a new one calling with tags as
- -- argument.
- -- This is done here because order of tags can change
- data[tag] = {}
- for kb, b in ipairs(buttons) do
- -- Copy object
- data[tag][kb] = capi.button(b)
- data[tag][kb].press = function () b.press(tag) end
+ local text, bg, bg_image, bg_resize = label(tag)
+ w[k].text = text
+ if text then
+ w[k].bg, w[k].bg_image, w[k].bg_resize = bg, bg_image, bg_resize
+ if buttons then
+ if not data[tag] then
+ -- Replace press function by a new one calling with tags as
+ -- argument.
+ -- This is done here because order of tags can change
+ data[tag] = {}
+ for kb, b in ipairs(buttons) do
+ -- Copy object
+ data[tag][kb] = capi.button(b)
+ data[tag][kb].press = function () b.press(tag) end
+ end
end
+ w[k]:buttons(data[tag])
end
- w[k]:buttons(data[tag])
end
end
end
@@ -112,7 +117,8 @@ end
-- squares_sel Optional: a user provided image for selected squares.
-- squares_unsel Optional: a user provided image for unselected squares.
-- squares_resize Optional: true or false to resize squares.
--- @return A string to print and a background color.
+-- @return A string to print, a background color, a background image and a
+-- background resize value.
function taglist.label.all(t, args)
if not args then args = {} end
local theme = beautiful.get()
@@ -124,23 +130,26 @@ function taglist.label.all(t, args)
local taglist_squares_unsel = args.squares_unsel or theme.taglist_squares_unsel
local taglist_squares_resize = theme.taglist_squares_resize or args.squares_resize or "true"
local font = args.font or theme.taglist_font or theme.font or ""
- local text = ""
- local background = ""
+ local text = " "
local sel = capi.client.focus
local bg_color = nil
local fg_color = nil
+ local bg_image
+ local bg_resize = false
if t.selected then
bg_color = bg_focus
fg_color = fg_focus
end
if sel and sel:tags()[t] then
if taglist_squares_sel then
- background = "resize=\"" .. taglist_squares_resize .. "\" image=\"" .. taglist_squares_sel .. "\""
+ bg_image = capi.image(taglist_squares_sel)
+ bg_resize = taglist_squares_resize == "true"
end
else
local cls = t:clients()
if #cls > 0 and taglist_squares_unsel then
- background = "resize=\"" .. taglist_squares_resize .. "\" image=\"" .. taglist_squares_unsel .. "\""
+ bg_image = capi.image(taglist_squares_unsel)
+ bg_resize = taglist_squares_resize == "true"
end
for k, c in pairs(cls) do
if c.urgent then
@@ -151,12 +160,12 @@ function taglist.label.all(t, args)
end
end
if fg_color then
- text = text .. " "..util.escape(t.name).." "
+ text = text .. ""..util.escape(t.name)..""
else
- text = text .. " "..util.escape(t.name).." "
+ text = text .. util.escape(t.name)
end
- text = text .. ""
- return text, bg_color
+ text = text .. " "
+ return text, bg_color, bg_image, bg_resize
end
--- Return labels for a taglist widget with all *non empty* tags from screen.
@@ -168,7 +177,8 @@ end
-- fg_focus The foreground color for selected tag.
-- bg_urgent The background color for urgent tags.
-- fg_urgent The foreground color for urgent tags.
--- @return A string to print.
+-- @return A string to print, a background color, a background image and a
+-- background resize value.
function taglist.label.noempty(t, args)
if #t:clients() > 0 or t.selected then
return taglist.label.all(t, args)
@@ -195,6 +205,8 @@ local function tasklist_update(w, buttons, label, data)
w[i] = capi.widget({ type = "imagebox", align = "flex" })
w[i + 1] = capi.widget({ type = "textbox", align = "flex" })
w[i + 1]:margin({ left = 2, right = 2 })
+ w[i + 1].bg_resize = true
+ w[i + 1].bg_align = "right"
end
-- Remove widgets
elseif len > #clients then
@@ -220,7 +232,7 @@ local function tasklist_update(w, buttons, label, data)
w[k]:buttons(data[c])
w[k + 1]:buttons(data[c])
end
- w[k + 1].text, w[k + 1].bg = label(clients[(k + 1) / 2])
+ w[k + 1].text, w[k + 1].bg, w[k + 1].bg_image= label(clients[(k + 1) / 2])
w[k].bg = w[k + 1].bg
if w[k + 1].text then
-- Set icon
@@ -275,13 +287,13 @@ local function widget_tasklist_label_common(c, args)
local fg_urgent = args.fg_urgent or theme.tasklist_fg_urgent or theme.fg_urgent
local bg_urgent = args.bg_urgent or theme.tasklist_bg_urgent or theme.bg_urgent
local floating_icon = args.floating_icon or theme.tasklist_floating_icon
- local floating_icon_align = args.floating_icon_align or theme.tasklist_floating_icon_align or "right"
local font = args.font or theme.tasklist_font or theme.font or ""
local bg = nil
local text = ""
local name
+ local status_image
if client.floating.get(c) and floating_icon then
- text = text..""
+ status_image = capi.image(floating_icon)
end
if c.minimized then
name = util.escape(c.icon_name) or ""
@@ -302,7 +314,7 @@ local function widget_tasklist_label_common(c, args)
text = text .. name
end
text = text .. ""
- return text, bg
+ return text, bg, status_image
end
--- Return labels for a tasklist widget with clients from all tags and screen.
@@ -316,7 +328,7 @@ end
-- fg_focus The foreground color for focused client.
-- bg_urgent The background color for urgent clients.
-- fg_urgent The foreground color for urgent clients.
--- @return A string to print and a background color.
+-- @return A string to print, a background color and a status image.
function tasklist.label.allscreen(c, screen, args)
return widget_tasklist_label_common(c, args)
end
@@ -332,7 +344,7 @@ end
-- fg_focus The foreground color for focused client.
-- bg_urgent The background color for urgent clients.
-- fg_urgent The foreground color for urgent clients.
--- @return A string to print and a background color.
+-- @return A string to print, a background color and a status image.
function tasklist.label.alltags(c, screen, args)
-- Only print client on the same screen as this widget
if c.screen ~= screen then return end
@@ -350,7 +362,7 @@ end
-- fg_focus The foreground color for focused client.
-- bg_urgent The background color for urgent clients.
-- fg_urgent The foreground color for urgent clients.
--- @return A string to print and a background color.
+-- @return A string to print, a background color and a status image.
function tasklist.label.currenttags(c, screen, args)
-- Only print client on the same screen as this widget
if c.screen ~= screen then return end
@@ -367,14 +379,14 @@ end
-- @return A textbox widget configured as a button.
function button(args)
if not args or not args.image then return end
- args.type = "textbox"
+ local img_release = args.image
+ local img_press = img_release:crop(-2, -2, img_release.width, img_release.height)
+ args.type = "imagebox"
local w = capi.widget(args)
- local img_release = ""
- local img_press = ""
- w.text = img_release
- w:buttons({ capi.button({}, 1, function () w.text = img_press end, function () w.text = img_release end) })
- function w.mouse_leave(s) w.text = img_release end
- function w.mouse_enter(s) if capi.mouse.coords().buttons[1] then w.text = img_press end end
+ w.image = img_release
+ w:buttons({ capi.button({}, 1, function () w.image = img_press end, function () w.image = img_release end) })
+ function w.mouse_leave(s) w.image = img_release end
+ function w.mouse_enter(s) if capi.mouse.coords().buttons[1] then w.image = img_press end end
return w
end
diff --git a/structs.h b/structs.h
index f38ec60b..19138a80 100644
--- a/structs.h
+++ b/structs.h
@@ -32,6 +32,7 @@
#include "common/xutil.h"
#include "common/xembed.h"
#include "common/refcount.h"
+#include "common/tokenize.h"
/** Windows type */
typedef enum
diff --git a/widgets/imagebox.c b/widgets/imagebox.c
index e3dfecd3..a4eee33a 100644
--- a/widgets/imagebox.c
+++ b/widgets/imagebox.c
@@ -44,13 +44,15 @@ imagebox_geometry(widget_t *widget, int screen, int height, int width)
{
if(d->resize)
{
- geometry.width = ((double) height / (double) d->image->height) * d->image->width;
- geometry.height = height;
+ double ratio = (double) height / d->image->height;
+ geometry.width = ratio * d->image->width;
if(geometry.width > width)
{
geometry.width = 0;
geometry.height = 0;
}
+ else
+ geometry.height = height;
}
else if(d->image->width <= width)
{
@@ -91,6 +93,7 @@ imagebox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry,
draw_rectangle(ctx, geometry, 1.0, true, &d->bg);
int y = geometry.y;
+ double ratio = d->resize ? (double) geometry.height / d->image->height : 1;
switch(d->valign)
{
case AlignBottom:
@@ -103,7 +106,7 @@ imagebox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry,
break;
}
- draw_image(ctx, geometry.x, y, d->resize ? ctx->height : 0, d->image);
+ draw_image(ctx, geometry.x, y, ratio, d->image);
}
}
diff --git a/widgets/textbox.c b/widgets/textbox.c
index dd3236cc..3d486300 100644
--- a/widgets/textbox.c
+++ b/widgets/textbox.c
@@ -27,18 +27,13 @@ extern awesome_t globalconf;
/** The textbox private data structure */
typedef struct
{
- /** Textbox text */
- char *text;
- /** Textbox text length */
- ssize_t len;
+ draw_text_context_t data;
/** Textbox width */
int width;
/** Extents */
area_t extents;
PangoEllipsizeMode ellip;
PangoWrapMode wrap;
- /** Draw parser data */
- draw_parser_data_t pdata;
/** Border */
struct
{
@@ -51,6 +46,12 @@ typedef struct
padding_t margin;
/** Background color */
xcolor_t bg;
+ /** Background image */
+ image_t *bg_image;
+ /** Background resize to wibox height. */
+ bool bg_resize;
+ /** Background alignment */
+ alignment_t bg_align;
} textbox_data_t;
static area_t
@@ -65,14 +66,13 @@ textbox_geometry(widget_t *widget, int screen, int height, int width)
geometry.width = d->width;
else if(widget->align == AlignFlex)
geometry.width = width;
- else
+ else if(d->bg_image)
{
- geometry.width = MIN(d->extents.width, width);
-
- if(d->pdata.bg_image)
- geometry.width = MAX(geometry.width,
- d->pdata.bg_resize ? ((double) d->pdata.bg_image->width / (double) d->pdata.bg_image->height) * geometry.height : d->pdata.bg_image->width);
+ double ratio = d->bg_resize ? (double) geometry.height / d->bg_image->height : 1;
+ geometry.width = MIN(width, MAX(d->extents.width, MAX(d->width, d->bg_image->width * ratio)));
}
+ else
+ geometry.width = MIN(d->extents.width, width);
return geometry;
}
@@ -95,8 +95,30 @@ textbox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry,
if(d->border.width > 0)
draw_rectangle(ctx, geometry, d->border.width, false, &d->border.color);
- draw_text(ctx, globalconf.font, d->ellip, d->wrap, d->align, &d->margin,
- geometry, d->text, d->len, &d->pdata, &d->extents);
+ if(d->bg_image)
+ {
+ double ratio = d->bg_resize ? (double) geometry.height / d->bg_image->height : 1;
+ /* check there is enough space to draw the image */
+ if(ratio * d->bg_image->width <= geometry.width)
+ {
+ int x = geometry.x;
+ int y = geometry.y;
+ switch(d->bg_align)
+ {
+ case AlignCenter:
+ x += (geometry.width - d->bg_image->width * ratio) / 2;
+ break;
+ case AlignRight:
+ x += geometry.width - d->bg_image->width * ratio;
+ break;
+ default:
+ break;
+ }
+ draw_image(ctx, x, y, ratio, d->bg_image);
+ }
+ }
+
+ draw_text(ctx, &d->data, globalconf.font, d->ellip, d->wrap, d->align, &d->margin, geometry, &d->extents);
}
/** Delete a textbox widget.
@@ -106,8 +128,7 @@ static void
textbox_destructor(widget_t *w)
{
textbox_data_t *d = w->data;
- draw_parser_data_wipe(&d->pdata);
- p_delete(&d->text);
+ draw_text_context_wipe(&d->data);
p_delete(&d);
}
@@ -140,6 +161,9 @@ luaA_textbox_margin(lua_State *L)
* \lfield align Text alignment, left, center or right.
* \lfield margin Method to pass text margin: a table with top, left, right and bottom keys.
* \lfield bg Background color.
+ * \lfield bg_image Background image.
+ * \lfield bg_align Background image alignment.
+ * \lfield bg_resize Background resize.
*/
static int
luaA_textbox_index(lua_State *L, awesome_token_t token)
@@ -149,6 +173,17 @@ luaA_textbox_index(lua_State *L, awesome_token_t token)
switch(token)
{
+ case A_TK_BG_RESIZE:
+ lua_pushboolean(L, d->bg_resize);
+ return 1;
+ case A_TK_BG_ALIGN:
+ lua_pushstring(L, draw_align_tostr(d->bg_align));
+ return 1;
+ case A_TK_BG_IMAGE:
+ if(d->bg_image)
+ return luaA_image_userdata_new(L, d->bg_image);
+ else
+ return 0;
case A_TK_BG:
return luaA_pushcolor(L, &d->bg);
case A_TK_MARGIN:
@@ -164,8 +199,12 @@ luaA_textbox_index(lua_State *L, awesome_token_t token)
luaA_pushcolor(L, &d->border.color);
return 1;
case A_TK_TEXT:
- lua_pushstring(L, d->text);
- return 1;
+ if(d->data.len > 0)
+ {
+ lua_pushlstring(L, d->data.text, d->data.len);
+ return 1;
+ }
+ return 0;
case A_TK_WIDTH:
lua_pushnumber(L, d->width);
return 1;
@@ -214,9 +253,29 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
widget_t **widget = luaA_checkudata(L, 1, "widget");
const char *buf = NULL;
textbox_data_t *d = (*widget)->data;
+ image_t **image = NULL;
switch(token)
{
+ case A_TK_BG_ALIGN:
+ buf = luaL_checklstring(L, 3, &len);
+ d->bg_align = draw_align_fromstr(buf, len);
+ break;
+ case A_TK_BG_RESIZE:
+ d->bg_resize = luaA_checkboolean(L, 3);
+ break;
+ case A_TK_BG_IMAGE:
+ if(lua_isnil(L, 3)
+ || (image = luaA_checkudata(L, 3, "image")))
+ {
+ /* unref image */
+ image_unref(&d->bg_image);
+ if(image)
+ d->bg_image = image_ref(image);
+ else
+ d->bg_image = NULL;
+ }
+ break;
case A_TK_BG:
if(lua_isnil(L, 3))
p_clear(&d->bg, 1);
@@ -239,21 +298,26 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
|| (buf = luaL_checklstring(L, 3, &len)))
{
/* delete */
- draw_parser_data_wipe(&d->pdata);
- /* reinit since we are giving it as arg to draw_text unconditionally */
- draw_parser_data_init(&d->pdata);
- p_delete(&d->text);
+ draw_text_context_wipe(&d->data);
+ p_clear(&d->data, 1);
if(buf)
{
- a_iso2utf8(buf, len, &d->text, &d->len);
- d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata);
+ char *text;
+ ssize_t tlen;
+ /* if text has been converted to UTF-8 */
+ if(draw_iso2utf8(buf, len, &text, &tlen))
+ {
+ draw_text_context_init(&d->data, text, tlen);
+ p_delete(&text);
+ }
+ else
+ draw_text_context_init(&d->data, buf, len);
+
+ d->extents = draw_text_extents(&d->data, globalconf.font);
}
else
- {
- d->len = 0;
p_clear(&d->extents, 1);
- }
}
break;
case A_TK_WIDTH: