This is an automated email generated because a ref change occurred in the
git repository for project wmaker-crm.git.
The branch, master has been updated
via 2901b418add8c4626d683b59ce27b346113dd22d (commit)
from ae6b03e50f01c81f9235859c96b4adc5784ab5d6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2901b418add8c4626d683b59ce27b346113dd22d
Author: David Maciejak <
david.m...@gmail.com>
Date: Mon, 9 Feb 2026 18:14:01 -0500
URL: <
https://repo.or.cz/wmaker-crm.git/2901b418add8c462>
wmaker: add window app icon to the window list
This patch is adding the app icon in between the flags icon and
the window name from the window list.
Feature request from
https://github.com/window-maker/wmaker/issues/19
It is disabled by default, it needs WindowListAppIcons to be
set to YES manually in the conf file or "Show app icons in window list."
enabled from WPrefs expert panel.
---
WPrefs.app/Expert.c | 3 ++
WindowMaker/Defaults/WindowMaker.in | 1 +
src/WindowMaker.h | 1 +
src/defaults.c | 2 ++
src/menu.c | 31 ++++++++++++++++++
src/menu.h | 1 +
src/switchmenu.c | 50 +++++++++++++++++++++++++++++
7 files changed, 89 insertions(+)
diff --git a/WPrefs.app/Expert.c b/WPrefs.app/Expert.c
index f7b7c7cefd8a..6ef6307ddc8f 100644
--- a/WPrefs.app/Expert.c
+++ b/WPrefs.app/Expert.c
@@ -78,6 +78,9 @@ static struct expert_option {
{ N_("Ignore minimized windows when cycling."),
/* default: */ False, OPTION_WMAKER, "CycleIgnoreMinimized" },
+ { N_("Show app icons in window list."),
+ /* default: */ False, OPTION_WMAKER, "WindowListAppIcons" },
+
{ N_("Show switch panel when cycling windows."),
/* default: */ True, OPTION_WMAKER_ARRAY, "SwitchPanelImages" },
diff --git a/WindowMaker/Defaults/WindowMaker.in b/WindowMaker/Defaults/WindowMaker.in
index 0cc0f65485c3..49cd181f5183 100644
--- a/WindowMaker/Defaults/WindowMaker.in
+++ b/WindowMaker/Defaults/WindowMaker.in
@@ -254,4 +254,5 @@
CycleActiveHeadOnly = NO;
CycleAllWorkspaces = NO;
CycleIgnoreMinimized = NO;
+ WindowListAppIcons = NO;
}
diff --git a/src/WindowMaker.h b/src/WindowMaker.h
index 23ca87418628..75464fdfe9ae 100644
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -479,6 +479,7 @@ extern struct WPreferences {
int hot_corner_delay; /* Delay after which the hot corner is triggered */
int hot_corner_edge; /* Hot corner edge size */
char *hot_corner_actions[4]; /* Action of each corner */
+ char window_list_app_icons; /* Show app icons in window list */
struct {
#ifdef USE_ICCCM_WMREPLACE
diff --git a/src/defaults.c b/src/defaults.c
index 8720b4ac5fb6..43860599da45 100644
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -534,6 +534,8 @@ WDefaultEntry optionList[] = {
&wPreferences.hot_corner_edge, getInt, NULL, NULL, NULL},
{"HotCornerActions", "(\"None\", \"None\", \"None\", \"None\")", &wPreferences,
NULL, getPropList, setHotCornerActions, NULL, NULL},
+ {"WindowListAppIcons", "NO", NULL,
+ &wPreferences.window_list_app_icons, getBool, NULL, NULL, NULL},
/* style options */
diff --git a/src/menu.c b/src/menu.c
index e84b1caa5105..7d3b69db9712 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -267,6 +267,7 @@ WMenuEntry *wMenuInsertCallback(WMenu *menu, int index, const char *text,
entry = wmalloc(sizeof(WMenuEntry));
entry->flags.enabled = 1;
entry->text = wstrdup(text);
+ entry->icon = NULL;
entry->cascade = -1;
entry->clientdata = clientdata;
entry->callback = callback;
@@ -369,6 +370,9 @@ void wMenuRemoveItem(WMenu * menu, int index)
if (menu->entries[index]->text)
wfree(menu->entries[index]->text);
+ if (menu->entries[index]->icon)
+ wPixmapDestroy(menu->entries[index]->icon);
+
if (menu->entries[index]->rtext)
wfree(menu->entries[index]->rtext);
@@ -499,6 +503,10 @@ void wMenuRealize(WMenu * menu)
text = menu->entries[i]->text;
width = WMWidthOfString(scr->menu_entry_font, text, strlen(text)) + 10;
+ if (wPreferences.window_list_app_icons && menu->entries[i]->icon) {
+ width += menu->entries[i]->icon->width + 4;
+ }
+
if (menu->entries[i]->flags.indicator) {
width += MENU_INDICATOR_SPACE;
}
@@ -562,6 +570,9 @@ void wMenuDestroy(WMenu * menu, int recurse)
wfree(menu->entries[i]->text);
+ if (menu->entries[i]->icon)
+ wPixmapDestroy(menu->entries[i]->icon);
+
if (menu->entries[i]->rtext)
wfree(menu->entries[i]->rtext);
#ifdef USER_MENU
@@ -711,6 +722,26 @@ static void paintEntry(WMenu * menu, int index, int selected)
if (entry->flags.indicator)
x += MENU_INDICATOR_SPACE + 2;
+ if (wPreferences.window_list_app_icons && entry->icon && entry->icon->image != None) {
+ int ix = x;
+ int iy = y + (h - entry->icon->height) / 2;
+
+ if (entry->icon->mask != None) {
+ XSetClipMask(dpy, scr->copy_gc, entry->icon->mask);
+ XSetClipOrigin(dpy, scr->copy_gc, ix, iy);
+ } else {
+ XSetClipMask(dpy, scr->copy_gc, None);
+ XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
+ }
+
+ XCopyArea(dpy, entry->icon->image, win, scr->copy_gc,
+ 0, 0, entry->icon->width, entry->icon->height, ix, iy);
+ XSetClipMask(dpy, scr->copy_gc, None);
+ XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
+
+ x += entry->icon->width + 4;
+ }
+
WMDrawString(scr->wmscreen, win, color, scr->menu_entry_font,
x, 3 + y + wPreferences.menu_text_clearance, entry->text, strlen(entry->text));
diff --git a/src/menu.h b/src/menu.h
index 60ff95559b14..036403bdca2c 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -46,6 +46,7 @@ typedef struct WMenuEntry {
int order;
char *text; /* entry text */
char *rtext; /* text to show in the right part */
+ struct WPixmap *icon; /* optional icon displayed before the text */
void (*callback)(struct WMenu *menu, struct WMenuEntry *entry);
void (*free_cdata)(void *data); /* proc to be used to free clientdata */
void *clientdata; /* data to pass to callback */
diff --git a/src/switchmenu.c b/src/switchmenu.c
index 551b4e583928..a8c3937f9ab1 100644
--- a/src/switchmenu.c
+++ b/src/switchmenu.c
@@ -48,6 +48,50 @@ static int initialized = 0;
static void observer(void *self, WMNotification * notif);
static void wsobserver(void *self, WMNotification * notif);
+static WPixmap *switchMenuIconForWindow(WScreen *scr, WWindow *wwin)
+{
+ RImage *image = NULL;
+ WPixmap *pix;
+ WApplication *wapp;
+ int max_size;
+
+ if (!scr || !wwin)
+ return NULL;
+
+ max_size = WMFontHeight(scr->menu_entry_font) + 2;
+ if (max_size < 12)
+ max_size = 12;
+
+ /* Prefer the actual appicon image when available */
+ wapp = wApplicationOf(wwin->main_window);
+ if (wapp && wapp->app_icon && wapp->app_icon->icon && wapp->app_icon->icon->file_image) {
+ image = RRetainImage(wapp->app_icon->icon->file_image);
+ }
+
+ /* Fall back to _NET_WM_ICON, then the default icon */
+ if (!image && !WFLAGP(wwin, always_user_icon) && wwin->net_icon_image)
+ image = RRetainImage(wwin->net_icon_image);
+ if (!image)
+ image = get_icon_image(scr, wwin->wm_instance, wwin->wm_class, max_size);
+
+ if (!image)
+ return NULL;
+
+ image = wIconValidateIconSize(image, max_size);
+ if (!image)
+ return NULL;
+
+ pix = wmalloc(sizeof(WPixmap));
+ memset(pix, 0, sizeof(WPixmap));
+ RConvertImageMask(scr->rcontext, image, &pix->image, &pix->mask, 128);
+ pix->width = image->width;
+ pix->height = image->height;
+ pix->depth = scr->w_depth;
+
+ RReleaseImage(image);
+ return pix;
+}
+
/*
* FocusWindow
*
@@ -216,6 +260,8 @@ void UpdateSwitchMenu(WScreen * scr, WWindow * wwin, int action)
entry = wMenuInsertCallback(switchmenu, idx, t, focusWindow, wwin);
wfree(t);
+ entry->icon = switchMenuIconForWindow(scr, wwin);
+
entry->flags.indicator = 1;
entry->rtext = wmalloc(MAX_WORKSPACENAME_WIDTH + 8);
if (IS_OMNIPRESENT(wwin))
@@ -273,6 +319,7 @@ void UpdateSwitchMenu(WScreen * scr, WWindow * wwin, int action)
if (entry->rtext) {
int idx = -1;
char *t, *rt;
+ WPixmap *ipix;
int it, ion;
if (IS_OMNIPRESENT(wwin)) {
@@ -285,6 +332,8 @@ void UpdateSwitchMenu(WScreen * scr, WWindow * wwin, int action)
rt = entry->rtext;
entry->rtext = NULL;
+ ipix = entry->icon;
+ entry->icon = NULL;
t = entry->text;
entry->text = NULL;
@@ -300,6 +349,7 @@ void UpdateSwitchMenu(WScreen * scr, WWindow * wwin, int action)
entry = wMenuInsertCallback(switchmenu, idx, t, focusWindow, wwin);
wfree(t);
entry->rtext = rt;
+ entry->icon = ipix;
entry->flags.indicator = 1;
entry->flags.indicator_type = it;
entry->flags.indicator_on = ion;
-----------------------------------------------------------------------
Summary of changes:
WPrefs.app/Expert.c | 3 ++
WindowMaker/Defaults/WindowMaker.in | 1 +
src/WindowMaker.h | 1 +
src/defaults.c | 2 ++
src/menu.c | 31 ++++++++++++++++++
src/menu.h | 1 +
src/switchmenu.c | 50 +++++++++++++++++++++++++++++
7 files changed, 89 insertions(+)
repo.or.cz automatic notification. Contact project admin
crm...@gmail.com
if you want to unsubscribe, or site admin
ad...@repo.or.cz if you receive
no reply.
--
wmaker-crm.git ("The Window Maker window manager")