aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-02-03 03:36:47 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-02-03 16:59:00 +0300
commit9b45bbe7a2061d46fb4a062c2e30ba2fbfae1219 (patch)
tree01f6b1379360a9e8fbbef07628bce2c2dfdfbd03
parent722582c552e5a2c9c37e713a711b31788c28b833 (diff)
downloadst-fork-9b45bbe7a2061d46fb4a062c2e30ba2fbfae1219.tar.gz
inherit window icon from embedded (Xembed) application
* This is largely taken from tabbed's "icon" patch (cf. xseticon()): https://tools.suckless.org/tabbed/patches/icon/ * I found that some applications that show their icon flawlessly in the WM won't work (neither in st, nor in tabbed). This was the case with SciTECO, but it could be resolved by reordering some statements. * Once the embedded application terminates, we try to remove the icon again. `xprop` confirms that this worked. Unfortunately, Awesome WM will continue to show the old icon, which is probably an Awesome WM bug. Perhaps we should therefore apply this patch on top of netwmicon (FIXME): https://st.suckless.org/patches/netwmicon/
-rw-r--r--x.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/x.c b/x.c
index 6d5f1a7..ca4c57e 100644
--- a/x.c
+++ b/x.c
@@ -197,6 +197,7 @@ static void destroynotify(XEvent *e);
static void sendxembed(long msg, long detail, long d1, long d2);
static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void updatetitle(Window win);
+static void updateicon(Window win);
static void run(void);
static void usage(void);
@@ -525,6 +526,7 @@ propnotify(XEvent *e)
{
XPropertyEvent *xpev;
Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0);
+ Atom wmicon = XInternAtom(xw.dpy, "_NET_WM_ICON", 0);
xpev = &e->xproperty;
if (xpev->state == PropertyNewValue &&
@@ -534,6 +536,9 @@ propnotify(XEvent *e)
} else if (xpev->state != PropertyDelete && xpev->atom == XA_WM_NAME &&
embed == xpev->window) {
updatetitle(embed);
+ } else if ((xpev->atom == wmicon || xpev->state == PropertyNewValue && xpev->atom == XA_WM_HINTS) &&
+ embed == xpev->window) {
+ updateicon(embed);
}
}
@@ -778,6 +783,7 @@ createnotify(XEvent *e)
XSelectInput(xw.dpy, embed, PropertyChangeMask | StructureNotifyMask | EnterWindowMask);
updatetitle(embed);
+ updateicon(embed);
XMapWindow(xw.dpy, embed);
sendxembed(XEMBED_EMBEDDED_NOTIFY, 0, xw.win, 0);
@@ -854,6 +860,46 @@ updatetitle(Window win)
}
void
+updateicon(Window win)
+{
+ Atom ret_type;
+ XWMHints *wmh, *cwmh;
+ int ret_format;
+ unsigned long ret_nitems, ret_nleft;
+ long offset = 0L;
+ unsigned char *data = NULL;
+
+ Atom wmicon = XInternAtom(xw.dpy, "_NET_WM_ICON", 0);
+ XDeleteProperty(xw.dpy, xw.win, wmicon);
+
+ wmh = XGetWMHints(xw.dpy, xw.win);
+ wmh->flags &= ~(IconPixmapHint | IconMaskHint);
+ wmh->icon_pixmap = wmh->icon_mask = None;
+
+ if (win) {
+ if (XGetWindowProperty(xw.dpy, win, wmicon, offset, LONG_MAX, False,
+ XA_CARDINAL, &ret_type, &ret_format, &ret_nitems,
+ &ret_nleft, &data) == Success &&
+ ret_type == XA_CARDINAL && ret_format == 32) {
+ XChangeProperty(xw.dpy, xw.win, wmicon, XA_CARDINAL, 32,
+ PropModeReplace, data, ret_nitems);
+ } else if ((cwmh = XGetWMHints(xw.dpy, win)) && cwmh->flags & IconPixmapHint) {
+ wmh->flags |= IconPixmapHint;
+ wmh->icon_pixmap = cwmh->icon_pixmap;
+ if (cwmh->flags & IconMaskHint) {
+ wmh->flags |= IconMaskHint;
+ wmh->icon_mask = cwmh->icon_mask;
+ }
+ XFree(cwmh);
+ }
+ }
+
+ XSetWMHints(xw.dpy, xw.win, wmh);
+ XFree(wmh);
+ XFree(data);
+}
+
+void
xresize(int col, int row)
{
win.tw = col * win.cw;
@@ -1826,6 +1872,9 @@ void
unmap(XEvent *ev)
{
if (embed == ev->xunmap.window) {
+ /* FIXME: restore the previous window title? */
+ /* FIXME: Does not remove the icon */
+ updateicon(0);
embed = 0;
XRaiseWindow(xw.dpy, xw.win);
XSetInputFocus(xw.dpy, xw.win, RevertToParent, CurrentTime);