diff options
-rw-r--r-- | .SRCINFO | 36 | ||||
-rw-r--r-- | PKGBUILD | 77 | ||||
-rw-r--r-- | iconsupport.patch | 331 |
3 files changed, 444 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..79102667cb08 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,36 @@ +pkgbase = i3-wm-iconpatch + pkgdesc = An improved dynamic tiling window manager (with titlebar icon patch) + pkgver = 4.10.2 + pkgrel = 1 + url = http://i3wm.org/ + arch = i686 + arch = x86_64 + groups = i3 + license = BSD + makedepends = bison + makedepends = flex + makedepends = pkg-config + depends = xcb-util-cursor + depends = xcb-util-keysyms + depends = xcb-util-wm + depends = libev + depends = yajl + depends = startup-notification + depends = pango + depends = libxkbcommon-x11 + optdepends = dmenu: As menu. + optdepends = i3lock: For locking your screen. + optdepends = i3status: To display systeminformation with a bar. + provides = i3-wm + conflicts = i3-wm + options = docs + options = !strip + source = http://i3wm.org/downloads/i3-4.10.2.tar.bz2 + source = http://i3wm.org/downloads/i3-4.10.2.tar.bz2.asc + source = iconsupport.patch + sha1sums = dc50d112645b9838d05e5864dc09a160c4cec8a1 + sha1sums = SKIP + sha1sums = 054a91ad3d83cfc01e2d02c90fda524f49616ebd + +pkgname = i3-wm-iconpatch + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..6b122d7ec49d --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,77 @@ +# Upstream Maintainer (i3-wm): Thorsten Töpper <atsutane-tu@freethoughts.de> +# Patch Contributor: Marius Muja <mariusm@cs.ubc.ca> +# Package Maintainer: cornholio <vigo.the.unholy.carpathian@gmail.com> + +pkgname=i3-wm-iconpatch +_pkgsourcename=i3 +pkgver=4.10.2 +pkgrel=1 +pkgdesc='An improved dynamic tiling window manager (with titlebar icon patch)' +arch=('i686' 'x86_64') +url='http://i3wm.org/' +license=('BSD') +provides=('i3-wm') +conflicts=('i3-wm') +groups=('i3') +depends=('xcb-util-cursor' 'xcb-util-keysyms' 'xcb-util-wm' 'libev' 'yajl' + 'startup-notification' 'pango' 'libxkbcommon-x11') +makedepends=('bison' 'flex' 'pkg-config') +optdepends=('dmenu: As menu.' + 'i3lock: For locking your screen.' + 'i3status: To display systeminformation with a bar.') +options=('docs' '!strip') +source=("http://i3wm.org/downloads/${_pkgsourcename}-${pkgver}.tar.bz2" + "http://i3wm.org/downloads/${_pkgsourcename}-${pkgver}.tar.bz2.asc" + "iconsupport.patch") +sha1sums=('dc50d112645b9838d05e5864dc09a160c4cec8a1' + 'SKIP' + '054a91ad3d83cfc01e2d02c90fda524f49616ebd') + +build() { + cd "$srcdir/$_pkgsourcename-$pkgver" + + # Apply icon titlebar patch + patch -p1 < "$srcdir/iconsupport.patch" + + # In order to avoid problems with bison use only a single process + MAKEFLAGS="-j1" + make +} + +package() { + cd "$srcdir/$_pkgsourcename-$pkgver" + + make DESTDIR="$pkgdir/" install + + install -Dm644 man/i3.1 \ + ${pkgdir}/usr/share/man/man1/i3.1 + install -Dm644 man/i3bar.1 \ + ${pkgdir}/usr/share/man/man1/i3bar.1 + install -Dm644 man/i3-config-wizard.1 \ + ${pkgdir}/usr/share/man/man1/i3-config-wizard.1 + install -Dm644 man/i3-input.1 \ + ${pkgdir}/usr/share/man/man1/i3-input.1 + install -Dm644 man/i3-msg.1 \ + ${pkgdir}/usr/share/man/man1/i3-msg.1 + install -Dm644 man/i3-migrate-config-to-v4.1 \ + ${pkgdir}/usr/share/man/man1/i3-migrate-config-to-v4.1 + install -Dm644 man/i3-nagbar.1 \ + ${pkgdir}/usr/share/man/man1/i3-nagbar.1 + install -Dm644 man/i3-dmenu-desktop.1 \ + ${pkgdir}/usr/share/man/man1/i3-dmenu-desktop.1 + install -Dm644 man/i3-dump-log.1 \ + ${pkgdir}/usr/share/man/man1/i3-dump-log.1 + install -Dm644 man/i3-sensible-editor.1 \ + ${pkgdir}/usr/share/man/man1/i3-sensible-editor.1 + install -Dm644 man/i3-sensible-pager.1 \ + ${pkgdir}/usr/share/man/man1/i3-sensible-pager.1 + install -Dm644 man/i3-sensible-terminal.1 \ + ${pkgdir}/usr/share/man/man1/i3-sensible-terminal.1 + + install -Dm644 LICENSE \ + ${pkgdir}/usr/share/licenses/${pkgname}/LICENSE + + make clean +} + +# vim:set ts=2 sw=2 et: diff --git a/iconsupport.patch b/iconsupport.patch new file mode 100644 index 000000000000..476b1566cae5 --- /dev/null +++ b/iconsupport.patch @@ -0,0 +1,331 @@ +diff -rupN i3-4.8-original/common.mk i3-4.8-patched/common.mk +--- i3-4.8-original/common.mk 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/common.mk 2014-06-16 08:18:43.263744935 -0400 +@@ -1,6 +1,7 @@ + UNAME=$(shell uname) + DEBUG=1 + COVERAGE=0 ++USE_ICONS=1 + INSTALL=install + LN=ln + ifndef PREFIX +@@ -56,6 +57,9 @@ I3_CPPFLAGS += -DMINOR_VERSION=${MINOR_V + I3_CPPFLAGS += -DPATCH_VERSION=${PATCH_VERSION} + I3_CPPFLAGS += -DSYSCONFDIR=\"${SYSCONFDIR}\" + I3_CPPFLAGS += -DI3__FILE__=__FILE__ ++ifeq ($(USE_ICONS),1) ++I3_CPPFLAGS += -DUSE_ICONS ++endif + + + ## Libraries flags +@@ -104,6 +108,9 @@ XCB_WM_CFLAGS += $(call cflags_for_lib, + XCB_WM_LIBS := $(call ldflags_for_lib, xcb-icccm,xcb-icccm) + XCB_WM_LIBS += $(call ldflags_for_lib, xcb-xinerama,xcb-xinerama) + XCB_WM_LIBS += $(call ldflags_for_lib, xcb-randr,xcb-randr) ++ifeq ($(USE_ICONS),1) ++XCB_WM_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image) ++endif + + # Xlib + X11_CFLAGS := $(call cflags_for_lib, x11) +diff -rupN i3-4.8-original/include/atoms.xmacro i3-4.8-patched/include/atoms.xmacro +--- i3-4.8-original/include/atoms.xmacro 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/include/atoms.xmacro 2014-06-16 08:18:43.267078172 -0400 +@@ -19,6 +19,7 @@ xmacro(_NET_CURRENT_DESKTOP) + xmacro(_NET_ACTIVE_WINDOW) + xmacro(_NET_STARTUP_ID) + xmacro(_NET_WORKAREA) ++xmacro(_NET_WM_ICON) + xmacro(WM_PROTOCOLS) + xmacro(WM_DELETE_WINDOW) + xmacro(UTF8_STRING) +diff -rupN i3-4.8-original/include/data.h i3-4.8-patched/include/data.h +--- i3-4.8-original/include/data.h 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/include/data.h 2014-06-16 08:18:43.267078172 -0400 +@@ -377,6 +377,11 @@ struct Window { + + /** Depth of the window */ + uint16_t depth; ++ ++#ifdef USE_ICONS ++ /** Window icon, array of size 16x16 containing the ARGB pixels */ ++ uint32_t* icon; ++#endif + }; + + /** +diff -rupN i3-4.8-original/include/window.h i3-4.8-patched/include/window.h +--- i3-4.8-original/include/window.h 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/include/window.h 2014-06-16 08:20:18.780985665 -0400 +@@ -63,6 +63,12 @@ void window_update_role(i3Window *win, x + void window_update_hints(i3Window *win, xcb_get_property_reply_t *prop, bool *urgency_hint); + + /** ++ * Updates the _NET_WM_ICON ++ * ++ */ ++void window_update_icon(i3Window *win, xcb_get_property_reply_t *prop); ++ ++/** + * Updates the MOTIF_WM_HINTS. The container's border style should be set to + * `motif_border_style' if border style is not BS_NORMAL. + * +diff -rupN i3-4.8-original/src/manage.c i3-4.8-patched/src/manage.c +--- i3-4.8-original/src/manage.c 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/src/manage.c 2014-06-16 08:25:33.681888859 -0400 +@@ -92,6 +92,10 @@ void manage_window(xcb_window_t window, + role_cookie, startup_id_cookie, wm_hints_cookie, + wm_normal_hints_cookie, motif_wm_hints_cookie; + ++ #ifdef USE_ICONS ++ xcb_get_property_cookie_t wm_icon_cookie; ++ #endif ++ + geomc = xcb_get_geometry(conn, d); + + /* Check if the window is mapped (it could be not mapped when intializing and +@@ -161,6 +165,9 @@ void manage_window(xcb_window_t window, + wm_hints_cookie = xcb_icccm_get_wm_hints(conn, window); + wm_normal_hints_cookie = xcb_icccm_get_wm_normal_hints(conn, window); + motif_wm_hints_cookie = GET_PROPERTY(A__MOTIF_WM_HINTS, 5 * sizeof(uint64_t)); ++ #ifdef USE_ICONS ++ wm_icon_cookie = xcb_get_property_unchecked(conn, false, window, A__NET_WM_ICON, XCB_ATOM_CARDINAL, 0, UINT32_MAX); ++ #endif + + DLOG("Managing window 0x%08x\n", window); + +@@ -196,6 +203,10 @@ void manage_window(xcb_window_t window, + window_update_hints(cwindow, xcb_get_property_reply(conn, wm_hints_cookie, NULL), &urgency_hint); + border_style_t motif_border_style = BS_NORMAL; + window_update_motif_hints(cwindow, xcb_get_property_reply(conn, motif_wm_hints_cookie, NULL), &motif_border_style); ++ #ifdef USE_ICONS ++ window_update_icon(cwindow, xcb_get_property_reply(conn, wm_icon_cookie, NULL)); ++ #endif ++ + xcb_size_hints_t wm_size_hints; + if (!xcb_icccm_get_wm_size_hints_reply(conn, wm_normal_hints_cookie, &wm_size_hints, NULL)) + memset(&wm_size_hints, '\0', sizeof(xcb_size_hints_t)); +diff -rupN i3-4.8-original/src/render.c i3-4.8-patched/src/render.c +--- i3-4.8-original/src/render.c 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/src/render.c 2014-06-16 08:18:43.270411409 -0400 +@@ -215,6 +215,11 @@ void render_con(Con *con, bool render_fu + + /* find the height for the decorations */ + int deco_height = render_deco_height(); ++#ifdef USE_ICONS ++ /* minimum decoration height to allow icon to fit ++ * not actuuly required, icon would be cropped otherwise */ ++ deco_height = deco_height<16 ? 16 : deco_height; ++#endif + + /* precalculate the sizes to be able to correct rounding errors */ + int sizes[children]; +diff -rupN i3-4.8-original/src/tree.c i3-4.8-patched/src/tree.c +--- i3-4.8-original/src/tree.c 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/src/tree.c 2014-06-16 08:27:37.981631499 -0400 +@@ -258,6 +258,9 @@ bool tree_close(Con *con, kill_window_t + FREE(con->window->class_class); + FREE(con->window->class_instance); + i3string_free(con->window->name); ++ #ifdef USE_ICONS ++ FREE(con->window->icon); ++ #endif + FREE(con->window->ran_assignments); + FREE(con->window); + } +diff -rupN i3-4.8-original/src/window.c i3-4.8-patched/src/window.c +--- i3-4.8-original/src/window.c 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/src/window.c 2014-06-16 08:18:43.270411409 -0400 +@@ -311,3 +311,83 @@ void window_update_motif_hints(i3Window + #undef MWM_DECOR_BORDER + #undef MWM_DECOR_TITLE + } ++ ++#ifdef USE_ICONS ++/* ++ * Copy and resize icon if needed ++ */ ++void copy_icon_with_resize(uint32_t *dst, int width, int height, uint32_t* src, int s_width, int s_height) ++{ ++ int i, j; ++ if (width==s_width && height==s_height) { ++ /* easy case, same dimensions, just copy data */ ++ memcpy(dst, src, width*height*sizeof(uint32_t)); ++ } ++ else { ++ uint32_t* row = src; ++ int xstep = s_width/width; ++ int ystep = s_height/height*s_width; ++ ++ for(i=0; i < height; ++i) { ++ uint32_t* ptr = row; ++ for(j=0; j < width; ++j) { ++ *dst++ = *ptr; ++ ptr+=xstep; ++ } ++ row += ystep; ++ } ++ } ++} ++ ++ ++void window_update_icon(i3Window *win, xcb_get_property_reply_t *prop) ++{ ++ uint32_t *data = NULL; ++ uint64_t len = 0; ++ ++ if(!prop || prop->type != XCB_ATOM_CARDINAL || prop->format != 32) { ++ DLOG("_NET_WM_ICON is not set\n"); ++ FREE(prop); ++ return; ++ } ++ ++ uint32_t prop_value_len = xcb_get_property_value_length(prop); ++ uint32_t *prop_value = (uint32_t *) xcb_get_property_value(prop); ++ ++ /* Find the number of icons in the reply. */ ++ while(prop_value_len > (sizeof(uint32_t) * 2) && prop_value && prop_value[0] && prop_value[1]) ++ { ++ /* Check that the property is as long as it should be (in bytes), ++ handling integer overflow. "+2" to handle the width and height ++ fields. */ ++ const uint64_t crt_len = prop_value[0] * (uint64_t) prop_value[1]; ++ const uint64_t expected_len = (crt_len + 2) * 4; ++ if(expected_len > prop_value_len) ++ break; ++ ++ if (len==0 || (crt_len>=16*16 && crt_len<len)) { ++ len = crt_len; ++ data = prop_value; ++ } ++ if (len==16*16) break; // found 16 pixels icon ++ ++ /* Find pointer to next icon in the reply. */ ++ prop_value_len -= expected_len; ++ prop_value = (uint32_t *) (((uint8_t *) prop_value) + expected_len); ++ } ++ ++ if (!data ) { ++ DLOG("Could not get _NET_WM_ICON\n"); ++ free(prop); ++ return; ++ } ++ ++ LOG("Got _NET_WM_ICON of size: (%d,%d)\n", data[0], data[1]); ++ ++ FREE(win->icon); ++ win->icon = malloc(16*16*sizeof(uint32_t)); ++ copy_icon_with_resize(win->icon, 16, 16, data+2, data[0], data[1]); ++ ++ free(prop); ++} ++#endif /* USE_ICONS */ +diff -rupN i3-4.8-original/src/x.c i3-4.8-patched/src/x.c +--- i3-4.8-original/src/x.c 2014-06-15 13:12:43.000000000 -0400 ++++ i3-4.8-patched/src/x.c 2014-06-16 08:32:24.960007993 -0400 +@@ -11,6 +11,9 @@ + * + */ + #include "all.h" ++#ifdef USE_ICONS ++#include <xcb/xcb_image.h> ++#endif + + /* Stores the X11 window ID of the currently focused window */ + xcb_window_t focused_id = XCB_NONE; +@@ -301,6 +304,44 @@ void x_window_kill(xcb_window_t window, + free(event); + } + ++#ifdef USE_ICONS ++ ++static inline uint32_t pixel_blend(uint32_t d, uint32_t s) ++{ ++ const uint32_t a = (s >> 24) + 1; ++ ++ const uint32_t dstrb = d & 0xFF00FF; ++ const uint32_t dstg = d & 0xFF00; ++ ++ const uint32_t srcrb = s & 0xFF00FF; ++ const uint32_t srcg = s & 0xFF00; ++ ++ uint32_t drb = srcrb - dstrb; ++ uint32_t dg = srcg - dstg; ++ ++ drb *= a; ++ dg *= a; ++ drb >>= 8; ++ dg >>= 8; ++ ++ uint32_t rb = (drb + dstrb) & 0xFF00FF; ++ uint32_t g = (dg + dstg) & 0xFF00; ++ ++ return rb | g; ++} ++ ++/* ++ * Copy icon pixels, blend with background ++ */ ++void copy_with_pixel_blend(uint32_t *dst, uint32_t* src, uint32_t background) ++{ ++ int i; ++ for(i=0; i < 16*16; ++i) { ++ *dst++ = pixel_blend(background,*src++); ++ } ++} ++#endif ++ + /* + * Draws the decoration of the given container onto its parent. + * +@@ -530,12 +571,49 @@ void x_draw_decoration(Con *con) { + } + //DLOG("indent_level = %d, indent_mult = %d\n", indent_level, indent_mult); + int indent_px = (indent_level * 5) * indent_mult; ++ #ifdef USE_ICONS ++ if (win->icon) indent_px += 18; ++ #endif + + draw_text(win->name, + parent->pixmap, parent->pm_gc, + con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y, + con->deco_rect.width - 2 - indent_px); + ++ #ifdef USE_ICONS ++ /* Draw the icon */ ++ if (win->icon) { ++ xcb_image_t* icon; ++ ++ uint16_t width = 16; ++ uint16_t height = 16; ++ uint32_t icon_pixels[width*height]; ++ ++ copy_with_pixel_blend(icon_pixels, win->icon, p->color->background); ++ ++ icon = xcb_image_create_native( conn, ++ width, height, ++ XCB_IMAGE_FORMAT_Z_PIXMAP, ++ root_depth, ++ NULL, ++ width*height*4, ++ (uint8_t*)icon_pixels ++ ); ++ ++ if (icon) { ++ int icon_offset_y = (con->deco_rect.height - 16) / 2; ++ ++ xcb_image_put(conn, parent->pixmap, parent->pm_gc, ++ icon, con->deco_rect.x + indent_px - 16 , con->deco_rect.y + icon_offset_y, 0); ++ ++ xcb_image_destroy(icon); ++ } ++ else { ++ ELOG("Error creating XCB image\n"); ++ } ++ } ++ #endif ++ + after_title: + /* Since we don’t clip the text at all, it might in some cases be painted + * on the border pixels on the right side of a window. Therefore, we draw |