Hello community,

here is the log from the commit of package alttab for openSUSE:Factory checked 
in at 2020-07-24 12:10:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/alttab (Old)
 and      /work/SRC/openSUSE:Factory/.alttab.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "alttab"

Fri Jul 24 12:10:59 2020 rev:4 rq:822568 version:1.5.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/alttab/alttab.changes    2020-06-11 
14:54:30.595243600 +0200
+++ /work/SRC/openSUSE:Factory/.alttab.new.3592/alttab.changes  2020-07-24 
12:11:02.557904278 +0200
@@ -1,0 +2,11 @@
+Fri Jul 24 07:51:47 UTC 2020 - Michael Vetter <mvet...@suse.com>
+
+- Update to 1.5.0:
+  * Use xpm icons and pixmap directories.
+  * Use XDG_DATA_DIRS.
+  * Add extra keys: next/prev, cancel.
+  * Optimize main event loop.
+  * Fix numerous memleaks and overflows.
+  * Satisfy gcc 10 requirements.
+
+-------------------------------------------------------------------

Old:
----
  v1.4.0.tar.gz

New:
----
  v1.5.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ alttab.spec ++++++
--- /var/tmp/diff_new_pack.fOIASU/_old  2020-07-24 12:11:04.345906076 +0200
+++ /var/tmp/diff_new_pack.fOIASU/_new  2020-07-24 12:11:04.345906076 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           alttab
-Version:        1.4.0
+Version:        1.5.0
 Release:        0
 Summary:        Task Switcher
 License:        GPL-3.0-only

++++++ v1.4.0.tar.gz -> v1.5.0.tar.gz ++++++
++++ 2005 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/ChangeLog new/alttab-1.5.0/ChangeLog
--- old/alttab-1.4.0/ChangeLog  2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/ChangeLog  2020-07-23 10:24:20.000000000 +0200
@@ -1,3 +1,14 @@
+2020-07-23  Alexander Kulak  <sa-dev@odd.systems>
+
+       version 1.5.0
+
+       Use xpm icons and pixmap directories.
+       Use XDG_DATA_DIRS.
+       Add extra keys: next/prev, cancel.
+       Optimize main event loop.
+       Fix numerous memleaks and overflows.
+       Satisfy gcc 10 requirements.
+
 2019-05-01  Alexander Kulak  <sa-dev@odd.systems>
 
        version 1.4.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/INSTALL.md new/alttab-1.5.0/INSTALL.md
--- old/alttab-1.4.0/INSTALL.md 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/INSTALL.md 2020-07-23 10:24:20.000000000 +0200
@@ -27,6 +27,13 @@
 
 * In Alpine Linux, alttab is in _aports/testing_ repository.
 
+* In openSUSE, alttab is available in Tumbleweed and from the 
[X11:Utilities](https://build.opensuse.org/package/show/X11:Utilities/alttab) 
repository:
+
+    ```
+    zypper ar -f obs://X11:Utilities x11utils
+    zypper ref
+    zypper in alttab
+    ```
 
 Building from source
 --------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/README.md new/alttab-1.5.0/README.md
--- old/alttab-1.4.0/README.md  2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/README.md  2020-07-23 10:24:20.000000000 +0200
@@ -13,8 +13,9 @@
 **alttab** is X11 window switcher designed for minimalistic window managers
 or standalone X11 session.
 ```
-  alttab  [-w N] [-d N] [-sc N] [-mk str] [-kk str] [-bk str] [-mm N] [-bm N] 
-  [-t NxM] [-i NxM] [-vp str] [-p str] [-s N] [-theme name] [-bg color] 
+  alttab  [-w N] [-d N] [-sc N] [`-mk` <str>] [`-kk` <str>] [`-bk` <str>]
+  [`-pk` <str>] [`-nk` <str>] [`-ck` <str>] [`-mm` <N>] [`-bm` <N>]
+  [-t NxM] [-i NxM] [-vp str] [-p str] [-s N] [-theme name] [-bg color]
   [-fg color] [-frame color] [-font name] [-v|-vv]
 ```
 (see man page for details)
@@ -43,5 +44,5 @@
 [no-wm](https://github.com/patrickhaller/no-wm): use X11 without a window 
manager  
    
    
-alttab (C) Alexander Kulak &lt;sa-dev AT odd POINT systems&gt; 2016-2019
+alttab (C) Alexander Kulak &lt;sa-dev AT odd POINT systems&gt; 2016-2020
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/configure.ac new/alttab-1.5.0/configure.ac
--- old/alttab-1.4.0/configure.ac       2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/configure.ac       2020-07-23 10:24:20.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([alttab], [1.4.0])
+AC_INIT([alttab], [1.5.0])
 AM_INIT_AUTOMAKE([foreign subdir-objects])
 AC_CONFIG_SRCDIR([configure.ac])
 AC_CONFIG_HEADERS([config.h])
@@ -8,6 +8,7 @@
 PKG_CHECK_MODULES([xrender], [xrender])
 PKG_CHECK_MODULES([xrandr], [xrandr])
 PKG_CHECK_MODULES([libpng], [libpng])
+PKG_CHECK_MODULES([xpm], [xpm])
 
 AC_MSG_CHECKING(for standalone fts library)
 if pkg-config --exists libfts ; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/doc/README new/alttab-1.5.0/doc/README
--- old/alttab-1.4.0/doc/README 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/doc/README 2020-07-23 10:24:20.000000000 +0200
@@ -2,8 +2,9 @@
 or standalone X11 session.
 
   alttab  [-w N] [-d N] [-sc N] [`-mk` <str>] [`-kk` <str>] [`-bk` <str>]
-  [`-mm` <N>] [`-bm` <N>] [-t NxM] [-i NxM] [-vp str] [-p str] [-s N] 
-  [-theme name] [-bg color] [-fg color] [-frame color] [-font name] [-v|-vv]
+  [`-pk` <str>] [`-nk` <str>] [`-ck` <str>] [`-mm` <N>] [`-bm` <N>]
+  [-t NxM] [-i NxM] [-vp str] [-p str] [-s N] [-theme name] [-bg color]
+  [-fg color] [-frame color] [-font name] [-v|-vv]
 
 (see man page for details)
 
@@ -29,7 +30,7 @@
 Source
 ------
 
-Copyright 2017-2019 Alexander Kulak <sa-dev AT odd POINT systems>.
+Copyright 2017-2020 Alexander Kulak <sa-dev AT odd POINT systems>.
 License: GPLv3 (see COPYING).
 Repository: https://github.com/sagb/alttab
 Chat: #alttab on Freenode
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/doc/alttab.1 new/alttab-1.5.0/doc/alttab.1
--- old/alttab-1.4.0/doc/alttab.1       2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/doc/alttab.1       2020-07-23 10:24:20.000000000 +0200
@@ -1,13 +1,13 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "ALTTAB" "1" "April 2019" "" ""
+.TH "ALTTAB" "1" "July 2020" "" ""
 .
 .SH "NAME"
 \fBalttab\fR \- the task switcher
 .
 .SH "SYNOPSIS"
-\fBalttab\fR [\fB\-w\fR \fIN\fR] [\fB\-d\fR \fIN\fR] [\fB\-sc\fR \fIN\fR] 
[\fB\-mk\fR \fIstr\fR] [\fB\-kk\fR \fIstr\fR] [\fB\-bk\fR \fIstr\fR] 
[\fB\-mm\fR \fIN\fR] [\fB\-bm\fR \fIN\fR] [\fB\-t\fR \fINxM\fR] [\fB\-i\fR 
\fINxM\fR] [\fB\-vp\fR \fIstr\fR] [\fB\-p\fR \fIstr\fR] [\fB\-s\fR \fIN\fR] 
[\fB\-theme\fR \fIname\fR] [\fB\-bg\fR \fIcolor\fR] [\fB\-fg\fR \fIcolor\fR] 
[\fB\-frame\fR \fIcolor\fR] [\fB\-font\fR \fIname\fR] [\fB\-v\fR|\fB\-vv\fR]
+\fBalttab\fR [\fB\-w\fR \fIN\fR] [\fB\-d\fR \fIN\fR] [\fB\-sc\fR \fIN\fR] 
[\fB\-mk\fR \fIstr\fR] [\fB\-kk\fR \fIstr\fR] [\fB\-bk\fR \fIstr\fR] 
[\fB\-pk\fR \fIstr\fR] [\fB\-nk\fR \fIstr\fR] [\fB\-ck\fR \fIstr\fR] 
[\fB\-mm\fR \fIN\fR] [\fB\-bm\fR \fIN\fR] [\fB\-t\fR \fINxM\fR] [\fB\-i\fR 
\fINxM\fR] [\fB\-vp\fR \fIstr\fR] [\fB\-p\fR \fIstr\fR] [\fB\-s\fR \fIN\fR] 
[\fB\-theme\fR \fIname\fR] [\fB\-bg\fR \fIcolor\fR] [\fB\-fg\fR \fIcolor\fR] 
[\fB\-frame\fR \fIcolor\fR] [\fB\-font\fR \fIname\fR] [\fB\-v\fR|\fB\-vv\fR]
 .
 .SH "DESCRIPTION"
 The task switcher designed for minimalistic window managers or standalone X11 
session\.
@@ -136,6 +136,36 @@
 Keysym of backward scroll key\.
 .
 .TP
+\fB\-pk\fR \fIstr\fR
+resource: alttab\.prevkey\.keysym
+.
+.br
+default: no key assigned
+.
+.IP
+Keysym of auxiliary \'previous\' key\. For example, Left, H\.
+.
+.TP
+\fB\-nk\fR \fIstr\fR
+resource: alttab\.nextkey\.keysym
+.
+.br
+default: no key assigned
+.
+.IP
+Keysym of auxiliary \'next\' key\. For example, Right, L\.
+.
+.TP
+\fB\-ck\fR \fIstr\fR
+resource: alttab\.cancelkey\.keysym
+.
+.br
+default: Escape
+.
+.IP
+Keysym of auxiliary \'cancel\' key\. For example, Escape\.
+.
+.TP
 \fB\-mm\fR \fINUM\fR
 resource: alttab\.modifier\.mask
 .
@@ -227,7 +257,7 @@
 \fI1\fR: Load icon from file if not found in window attributes\.
 .
 .IP
-Alttab searches for PNG icons under:
+Alttab searches for PNG and XPM icons in $XDG_DATA_DIRS and also under:
 .
 .IP
 /usr/share/icons
@@ -245,6 +275,15 @@
 Directory structure should obey freedesktop standard, but desktop files are 
ignored, instead file name is expected to be equal to application class\. That 
is, if alttab doesn\'t recognize an icon for window of class foo, as obtained 
by \'xprop WM_CLASS\', then just drop a 32x32 icon into 
/usr/local/share/icons/hicolor/32x32/apps/foo\.png\.
 .
 .IP
+Also, alttab scans for icons in legacy directories without freedesktop 
directory structure:
+.
+.IP
+/usr/share/pixmaps
+.
+.br
+~/\.local/share/pixmaps
+.
+.IP
 \fI2\fR: Prefer icon from file when it matches requested size better (see 
\fB\-i\fR option)\.
 .
 .IP
@@ -333,7 +372,7 @@
 Run alttab after WM, or autodetection will fail\.
 .
 .SH "AUTHOR"
-Copyright 2017\-2019 Alexander Kulak \fB<sa\-dev AT odd POINT systems>\fR\.
+Copyright 2017\-2020 Alexander Kulak \fB<sa\-dev AT odd POINT systems>\fR\.
 .
 .SH "REPORTING BUGS"
 Please report issues on github \fIhttps://github\.com/sagb/alttab/issues\fR\.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/doc/alttab.1.ronn new/alttab-1.5.0/doc/alttab.1.ronn
--- old/alttab-1.4.0/doc/alttab.1.ronn  2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/doc/alttab.1.ronn  2020-07-23 10:24:20.000000000 +0200
@@ -2,7 +2,7 @@
 The source of alttab.1. Read doc/development.md.
 vim:ft=markdown
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 Copying and distribution of this file, with or without modification,
@@ -16,7 +16,7 @@
 
 ## SYNOPSIS
 
-`alttab` [`-w` <N>] [`-d` <N>] [`-sc` <N>] [`-mk` <str>] [`-kk` <str>] [`-bk` 
<str>] [`-mm` <N>] [`-bm` <N>] [`-t` <NxM>] [`-i` <NxM>] [`-vp` <str>] [`-p` 
<str>] [`-s` <N>] [`-theme` <name>] [`-bg` <color>] [`-fg` <color>] [`-frame` 
<color>] [`-font` <name>] [`-v`|`-vv`]
+`alttab` [`-w` <N>] [`-d` <N>] [`-sc` <N>] [`-mk` <str>] [`-kk` <str>] [`-bk` 
<str>] [`-pk` <str>] [`-nk` <str>] [`-mm` <N>] [`-bm` <N>] [`-t` <NxM>] [`-i` 
<NxM>] [`-vp` <str>] [`-p` <str>] [`-s` <N>] [`-theme` <name>] [`-bg` <color>] 
[`-fg` <color>] [`-frame` <color>] [`-font` <name>] [`-v`|`-vv`]
 
 ## DESCRIPTION
 
@@ -120,6 +120,26 @@
 
     Keysym of backward scroll key.
 
+  * `-pk` <str>:
+    resource: alttab.prevkey.keysym  
+    default: no key assigned
+
+    Keysym of auxiliary 'previous' key.
+    For example, Left, H.
+
+  * `-nk` <str>:
+    resource: alttab.nextkey.keysym  
+    default: no key assigned
+
+    Keysym of auxiliary 'next' key.
+    For example, Right, L.
+
+  * `-ck` <str>:
+    resource: alttab.cancelkey.keysym  
+    default: Escape
+
+    Keysym of auxiliary 'cancel' key.
+
   * `-mm` <NUM>:
     resource: alttab.modifier.mask  
 
@@ -196,7 +216,7 @@
       
       <1>: Load icon from file if not found in window attributes.
 
-      Alttab searches for PNG icons under:  
+      Alttab searches for PNG and XPM icons in $XDG_DATA_DIRS and also under:  
   
       /usr/share/icons  
       /usr/local/share/icons  
@@ -208,6 +228,12 @@
       That is, if alttab doesn't recognize an icon for window of class foo,
       as obtained by 'xprop WM_CLASS', then just drop a 32x32 icon into
       /usr/local/share/icons/hicolor/32x32/apps/foo.png.
+  
+      Also, alttab scans for icons in legacy directories without freedesktop 
directory
+      structure:  
+  
+      /usr/share/pixmaps  
+      ~/.local/share/pixmaps  
 
       <2>: Prefer icon from file when it matches requested size better (see 
`-i` option).
 
@@ -266,7 +292,7 @@
 
 ##AUTHOR
 
-Copyright 2017-2019 Alexander Kulak `<sa-dev AT odd POINT systems>`.
+Copyright 2017-2020 Alexander Kulak `<sa-dev AT odd POINT systems>`.
 
 ##REPORTING BUGS
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/doc/alttab.ad new/alttab-1.5.0/doc/alttab.ad
--- old/alttab-1.4.0/doc/alttab.ad      2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/doc/alttab.ad      2020-07-23 10:24:20.000000000 +0200
@@ -25,6 +25,14 @@
 ! grave (back apostrophe) instead of Tab
 !alttab.key.keysym:      grave
 
+! auxiliary 'previous' key
+!alttab.prevkey.keysym:      Left
+! auxiliary 'next' key
+!alttab.nextkey.keysym:      Right
+
+! auxiliary 'cancel' key
+!alttab.cancelkey.keysym:    Escape
+
 ! Limit the switcher to this rectangle 
 ! instead of default screen size
 !alttab.viewport:        1280x1024+1280+0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/doc/wm-setup.md new/alttab-1.5.0/doc/wm-setup.md
--- old/alttab-1.4.0/doc/wm-setup.md    2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/doc/wm-setup.md    2020-07-23 10:24:20.000000000 +0200
@@ -34,7 +34,7 @@
 metacity/MATE| 1 (auto)                    | see "MATE" section below       | 
 jwm          | 1 (auto)                    | comment A-Tab entry in .jwmrc  | 
see "jwm" section below
 openbox      | 1 (auto)                    | see "openbox" section below    |
-fluxbox      | 1 (auto)                    | see "fluxbox" section below    | 
`alttab &` in ~/.fluxbox/startup
+fluxbox      | 1 (auto)                    | see "fluxbox" section below    | 
see "fluxbox" section below
 icewm        | 1 (auto)                    | ?                              | ?
 matchbox     | 1 (auto, partial support)   | doesn't grab                   | ?
 enlightenment| 1 (auto)                    | ?                              | ?
@@ -129,9 +129,16 @@
     #Mod1 Shift Tab :PrevWindow {groups} (workspace=[current])
 
 ### startup
-In ~/.fluxbox/startup:
+To start alttab _after_ fluxbox, in `~/.fluxbox/startup` replace `exec 
fluxbox` with:
 
-    ...other apps...
-    alttab &
-    exec fluxbox
+    fluxbox &
+    fbpid=$!
+    sleep 3
+    {
+        alttab &
+        # ...other apps to run after fluxbox startup...
+    } &
+    wait $fbpid
+
+Details [here](http://fluxbox-wiki.org/Editing_the_startup_file.html).
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/Makefile.am new/alttab-1.5.0/src/Makefile.am
--- old/alttab-1.4.0/src/Makefile.am    2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/Makefile.am    2020-07-23 10:24:20.000000000 +0200
@@ -1,4 +1,4 @@
 bin_PROGRAMS = alttab
 alttab_SOURCES = alttab.c gui.c win.c x.c rp.c util.c ewmh.c icon.c pngd.c 
randr.c autil.c
-AM_CFLAGS = $(x11_CFLAGS) $(xft_CFLAGS) $(xrender_CFLAGS) $(xrandr_CFLAGS) 
$(libpng_CFLAGS) $(fts_CFLAGS) -Wall
-LIBS += $(x11_LIBS) $(xft_LIBS) $(xrender_LIBS) $(xrandr_LIBS) $(libpng_LIBS) 
$(fts_LIBS)
+AM_CFLAGS = $(x11_CFLAGS) $(xft_CFLAGS) $(xrender_CFLAGS) $(xrandr_CFLAGS) 
$(libpng_CFLAGS) $(fts_CFLAGS) $(xpm_CFLAGS) -Wall
+LIBS += $(x11_LIBS) $(xft_LIBS) $(xrender_LIBS) $(xrandr_LIBS) $(libpng_LIBS) 
$(fts_LIBS) $(xpm_LIBS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/alttab.c new/alttab-1.5.0/src/alttab.c
--- old/alttab-1.4.0/src/alttab.c       2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/alttab.c       2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Parsing options/resources, top-level keygrab functions and main().
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -54,6 +54,8 @@
    -kk str    keysym of main key\n\
    -mk str    keysym of main modifier\n\
    -bk str    keysym of backscroll modifier\n\
+   -pk str    keysym of 'prev' key\n\
+   -nk str    keysym of 'next' key\n\
    -mm N      (obsoleted) main modifier mask\n\
    -bm N      (obsoleted) backward scroll modifier mask\n\
     -t NxM    tile geometry\n\
@@ -106,6 +108,9 @@
         {"-mk", "*modifier.keysym", XrmoptionSepArg, NULL},
         {"-kk", "*key.keysym", XrmoptionSepArg, NULL},
         {"-bk", "*backscroll.keysym", XrmoptionSepArg, NULL},
+        {"-pk", "*prevkey.keysym", XrmoptionSepArg, NULL},
+        {"-nk", "*nextkey.keysym", XrmoptionSepArg, NULL},
+        {"-ck", "*cancelkey.keysym", XrmoptionSepArg, NULL},
         {"-t", "*tile.geometry", XrmoptionSepArg, NULL},
         {"-i", "*icon.geometry", XrmoptionSepArg, NULL},
         {"-vp", "*viewport", XrmoptionSepArg, NULL},
@@ -237,6 +242,9 @@
 
 #define  MC  g.option_modCode
 #define  KC  g.option_keyCode
+#define  prevC  g.option_prevCode
+#define  nextC  g.option_nextCode
+#define  cancelC  g.option_cancelCode
 #define  GMM  g.option_modMask
 #define  GBM  g.option_backMask
 
@@ -250,6 +258,21 @@
         die("%s\n", errmsg);
     KC = ksi != 0 ? ksi : XKeysymToKeycode(dpy, DEFKEYKS);
 
+    ksi = ksym_option_to_keycode(&db, XRMAPPNAME, "prevkey", &errmsg);
+    if (ksi == -1)
+        die("%s\n", errmsg);
+    prevC = ksi != 0 ? ksi : XKeysymToKeycode(dpy, DEFPREVKEYKS);
+
+    ksi = ksym_option_to_keycode(&db, XRMAPPNAME, "nextkey", &errmsg);
+    if (ksi == -1)
+        die("%s\n", errmsg);
+    nextC = ksi != 0 ? ksi : XKeysymToKeycode(dpy, DEFNEXTKEYKS);
+
+    ksi = ksym_option_to_keycode(&db, XRMAPPNAME, "cancelkey", &errmsg);
+    if (ksi == -1)
+        die("%s\n", errmsg);
+    cancelC = ksi != 0 ? ksi : XKeysymToKeycode(dpy, DEFCANCELKS);
+
     switch (xresource_load_int(&db, XRMAPPNAME, "modifier.mask", &(GMM))) {
     case 1:
         msg(-1,
@@ -427,7 +450,7 @@
 // grab Alt-Tab and Alt-Shift-Tab
 // note: exit() on failure
 //
-static int grabAllKeys(bool grabUngrab)
+static int grabKeysAtStartup(bool grabUngrab)
 {
     g.ignored_modmask = getOffendingModifiersMask(dpy); // or 0 for g.debug
     char *grabhint =
@@ -444,9 +467,26 @@
         die(grabhint, g.option_keyCode,
             g.option_modMask | g.option_backMask, g.ignored_modmask);
     }
+
     return 1;
 }
 
+//
+// Returns 0 if not an extra prev/next keycode, 1 if extra prev keycode, and 2 
if extra next keycode.
+//
+static int isPrevNextKey(unsigned int keycode)
+{
+    if (keycode == g.option_prevCode) {
+        return 1;
+    }
+    if (keycode == g.option_nextCode) {
+        return 2;
+    }
+    // if here then is neither
+    return 0;
+}
+
+
 int main(int argc, char **argv)
 {
 
@@ -469,7 +509,7 @@
     if (!startupGUItasks())
         die("startupGUItasks failed");
 
-    grabAllKeys(true);
+    grabKeysAtStartup(true);
     g.uiShowHasRun = false;
 
     struct timespec nanots;
@@ -502,17 +542,40 @@
         case KeyPress:
             msg(1, "Press %lx: %d-%d\n",
                 ev.xkey.window, ev.xkey.state, ev.xkey.keycode);
-            if (!((ev.xkey.state & g.option_modMask)
-                  && ev.xkey.keycode == g.option_keyCode)) {
-                break;
-            }                   // safety redundance
-            if (!g.uiShowHasRun) {
-                uiShow((ev.xkey.state & g.option_backMask));
-            } else {
-                if (ev.xkey.state & g.option_backMask) {
-                    uiPrevWindow();
-                } else {
-                    uiNextWindow();
+            if (ev.xkey.state & g.option_modMask) {  // alt
+                if (ev.xkey.keycode == g.option_keyCode) {  // tab
+                    // additional check, see #97
+                    XQueryKeymap(dpy, keys_pressed);
+                    if (!(keys_pressed[octet] & kmask)) {
+                        msg(1, "Wrong modifier, skip event\n");
+                        continue;
+                    }
+                    if (!g.uiShowHasRun) {
+                        uiShow((ev.xkey.state & g.option_backMask));
+                    } else {
+                        if (ev.xkey.state & g.option_backMask) {
+                            uiPrevWindow();
+                        } else {
+                            uiNextWindow();
+                        }
+                    }
+                } else if (ev.xkey.keycode == g.option_cancelCode) { // escape
+                    // additional check, see #97
+                    XQueryKeymap(dpy, keys_pressed);
+                    if (!(keys_pressed[octet] & kmask)) {
+                        msg(1, "Wrong modifier, skip event\n");
+                        continue;
+                    }
+                    uiSelectWindow(0);
+                } else {  // non-tab
+                    switch (isPrevNextKey(ev.xkey.keycode)) {
+                    case 1:
+                        uiPrevWindow();
+                        break;
+                    case 2:
+                        uiNextWindow();
+                        break;
+                    }
                 }
             }
             break;
@@ -562,8 +625,8 @@
     shutdownWin();
     shutdownGUI();
     XrmDestroyDatabase(db);
-    grabAllKeys(false);
+    grabKeysAtStartup(false);
 // not restoring error handler
     XCloseDisplay(dpy);
     return 0;
-}                               // main
+} // main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/alttab.h new/alttab-1.5.0/src/alttab.h
--- old/alttab-1.4.0/src/alttab.h       2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/alttab.h       2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Global includes.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -55,6 +55,9 @@
 #define DEFBACKMASK ShiftMask
 #define DEFMODKS    XK_Alt_L
 #define DEFKEYKS    XK_Tab
+#define DEFPREVKEYKS    XK_VoidSymbol
+#define DEFNEXTKEYKS    XK_VoidSymbol
+#define DEFCANCELKS XK_Escape
 
 #include "icon.h"
 
@@ -175,6 +178,8 @@
     char *option_theme;
     unsigned int option_modMask, option_backMask;
     KeyCode option_modCode, option_keyCode;
+    KeyCode option_prevCode, option_nextCode;
+    KeyCode option_cancelCode;
     Color color[NCOLORS];
     GC gcDirect, gcReverse, gcFrame;    // used in both gui.c and win.c
     unsigned int ignored_modmask;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/autil.c new/alttab-1.5.0/src/autil.c
--- old/alttab-1.4.0/src/autil.c        2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/autil.c        2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Helper functions specific to alttab.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/ewmh.c new/alttab-1.5.0/src/ewmh.c
--- old/alttab-1.4.0/src/ewmh.c 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/ewmh.c 2020-07-23 10:24:20.000000000 +0200
@@ -2,7 +2,7 @@
 Interface with EWMH-compatible window managers.
 Note: _WIN fallbacks are not part of EWMH or ICCCM, but kept here anyway.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/gui.c new/alttab-1.5.0/src/gui.c
--- old/alttab-1.4.0/src/gui.c  2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/gui.c  2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Draw and interface with our switcher window.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -171,7 +171,7 @@
                 msg(-1, "can't create GC to draw icon\n");
                 goto endIcon;
             }
-            if (wi->icon_mask != 0) {
+            if (wi->icon_mask != None) {
                 XSetClipMask(dpy, ic_gc, wi->icon_mask);
             }
             int or = XCopyArea(dpy,
@@ -227,6 +227,41 @@
     }
 }                               // prepareTile
 
+//
+// grab auxiliary keys: arrows
+// rely on pre-calculated g.ignored_modmask and g.option_modMask
+//
+static int grabKeysAtUiShow(bool grabUngrab)
+{
+    char *grabhint =
+        "Error while (un)grabbing key 0x%x with mask 0x%x/0x%x.\n";
+    if (g.option_prevCode != 0) {
+        if (!changeKeygrab
+            (root, grabUngrab, g.option_prevCode, g.option_modMask,
+             g.ignored_modmask)) {
+            msg(0, grabhint, g.option_prevCode, g.option_modMask, 
g.ignored_modmask);
+            return 0;
+        }
+    }
+    if (g.option_nextCode != 0) {
+        if (!changeKeygrab
+            (root, grabUngrab, g.option_nextCode, g.option_modMask,
+             g.ignored_modmask)) {
+            msg(0, grabhint, g.option_nextCode, g.option_modMask, 
g.ignored_modmask);
+            return 0;
+        }
+    }
+    if (g.option_cancelCode != 0) {
+        if (!changeKeygrab
+            (root, grabUngrab, g.option_cancelCode, g.option_modMask,
+             g.ignored_modmask)) {
+            msg(0, grabhint, g.option_cancelCode, g.option_modMask, 
g.ignored_modmask);
+            return 0;
+        }
+    }
+    return 1;
+}
+
 // PUBLIC
 
 //
@@ -490,6 +525,7 @@
 // note: x_setCommonPropertiesForAnyWindow does the same thing for any window
     XSelectInput(dpy, uiwin, ExposureMask | KeyPressMask | KeyReleaseMask
                  | ButtonPressMask | ButtonReleaseMask);
+    grabKeysAtUiShow(true);
 // set window type so that WM will hopefully not resize it
 // before mapping: 
https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html
     Atom at = XInternAtom(dpy, "ATOM", True);
@@ -607,6 +643,7 @@
 //
 int uiHide()
 {
+    grabKeysAtUiShow(false);
     // order is important: to set focus in Metacity,
     // our window must be destroyed first
     if (uiwin) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/icon.c new/alttab-1.5.0/src/icon.c
--- old/alttab-1.4.0/src/icon.c 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/icon.c 2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Icon object.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -45,8 +45,10 @@
     ic->app[0] = '\0';
     ic->src_path[0] = '\0';
     ic->src_w = ic->src_h = 0;
-    ic->drawable = ic->mask = 0;
+    ic->drawable = ic->mask = None;
     ic->drawable_allocated = false;
+    ic->ext = ICON_EXT_UNKNOWN;
+    ic->dir = ICON_DIR_FREEDESKTOP;
 
     return ic;
 }
@@ -58,6 +60,11 @@
 {
     if (ic->drawable_allocated) {
         XFreePixmap(dpy, ic->drawable);
+        /*
+        if (ic->mask != None) {
+            XFreePixmap(dpy, ic->mask);
+        }
+        */
     }
     free(ic);
 }
@@ -74,36 +81,40 @@
 }
 
 //
-// load all icons
-// (no pixmaps, just path and dimension)
+// build array of icon directories
+// return the number of elements or 0
 //
-int updateIconsFromFile(icon_t ** ihash)
+int allocIconDirs(char ** icon_dirs)
 {
     int hd;
     char *id2;
     int id2len;
-    char *icon_dirs[MAXICONDIRS];
-    int d_c, f_c;
-    FTS *ftsp;
-    FTSENT *p, *chp;
-    icon_t *iiter, *tmp;
-
-    int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
-    // XDG_DATA_DIRS ignored
     const char *icondir[] = {
         "/usr/share/icons",
         "/usr/local/share/icons",
         "~/.icons",
         "~/.local/share/icons",
+        "/usr/share/pixmaps",
+        "~/.local/share/pixmaps",
         NULL
     };
     int idndx = 0;
     int theme_len = strlen(g.option_theme);
     char *home = getenv("HOME");
-    int ret = 0;
+    char *xdgdd = getenv("XDG_DATA_DIRS");
+    bool legacy;
+    char *str1;
+    char *xdg;
+    char *saveptr1;
+    int j;
+    char *k;
+    int idsd;
 
     for (hd = 0; icondir[hd] != NULL; hd++) {
-        id2len = strlen(icondir[hd]) + 1 + theme_len + 1;
+        legacy = (strstr (icondir[hd], "pixmap") != NULL);
+        id2len = strlen(icondir[hd]) + 1;
+        if (!legacy)
+            id2len += theme_len + 1;
         if (icondir[hd][0] == '~') {
             if (home == NULL)
                 continue;
@@ -113,20 +124,84 @@
         if (!id2)
             return 0;
         if (icondir[hd][0] == '~')
-            snprintf(id2, id2len, "%s%s/%s", home, icondir[hd] + 1,
-                     g.option_theme);
+            snprintf(id2, id2len, "%s%s", home, icondir[hd] + 1);
         else
-            snprintf(id2, id2len, "%s/%s", icondir[hd], g.option_theme);
+            snprintf(id2, id2len, "%s", icondir[hd]);
+        if (!legacy) {
+            strcat(id2, "/");
+            strncat(id2, g.option_theme, theme_len);
+        }
         id2[id2len - 1] = '\0';
         icon_dirs[idndx] = id2;
         idndx++;
     }
+
+    if (xdgdd != NULL) {
+        for (j = 1, str1 = xdgdd; ; j++, str1 = NULL) {
+            xdg = strtok_r(str1, ":", &saveptr1);
+            if (xdg == NULL)
+                break;
+            msg(1, "xdg dir %d: %s\n", j, xdg);
+            // strip trailing "/"'s
+            for (k = xdg + strlen(xdg) - 1; *k == '/'; k--) {
+                *k = '\0';
+            }
+            id2len = strlen(xdg) + strlen("/icons/") + theme_len + 1;
+            id2 = malloc(id2len);
+            if (!id2)
+                return 0;
+            snprintf(id2, id2len, "%s/icons/%s", xdg, g.option_theme);
+            id2[id2len - 1] = '\0';
+            // search for duplicates
+            for (idsd = 0; idsd < idndx; idsd++) {
+                if (strncmp (icon_dirs[idsd], id2, id2len) == 0) {
+                    msg(1, "skip duplicate icon dir: %s\n", id2);
+                    free(id2); id2 = NULL;
+                    break;
+                }
+            }
+            if (id2 != NULL) {
+                icon_dirs[idndx] = id2;
+                idndx++;
+            }
+        }
+    }
+
     icon_dirs[idndx] = NULL;
     if (g.debug > 1) {
         for (idndx = 0; icon_dirs[idndx] != NULL; idndx++)
             msg(1, "icon dir: %s\n", icon_dirs[idndx]);
     }
+    return idndx;
+}
 
+//
+// free icon_dirs
+//
+void destroyIconDirs(char ** icon_dirs)
+{
+    int idndx;
+    for (idndx = 0; icon_dirs[idndx] != NULL; idndx++)
+        free(icon_dirs[idndx]);
+}
+
+//
+// load all icons
+// (no pixmaps, just path and dimension)
+//
+int updateIconsFromFile(icon_t ** ihash)
+{
+    char *icon_dirs[MAXICONDIRS];
+    int d_c, f_c;
+    FTS *ftsp;
+    FTSENT *p, *chp;
+    icon_t *iiter, *tmp;
+    int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
+    int ret = 0;
+
+    if (allocIconDirs(icon_dirs) <= 0) {
+        goto out;
+    }
     if ((ftsp = fts_open(icon_dirs, fts_options, NULL)) == NULL) {
         warn("fts_open");
         goto out;
@@ -145,7 +220,7 @@
             break;
         case FTS_F:
             //msg(1, "f %s\n", p->fts_path);
-            inspectIconFile(p);
+            inspectIconMeta(p);
             f_c++;
             break;
         default:
@@ -163,27 +238,26 @@
             }
         }
     }
-
     ret = 1;
 
 out:
-    for (idndx = 0; icon_dirs[idndx] != NULL; idndx++)
-        free(icon_dirs[idndx]);
-
+    destroyIconDirs(icon_dirs);
     return ret;
-}                               // updateIconsFromFile
+}   // updateIconsFromFile
 
 //
 // check if the file has better icon for given app than in g.ic
 // return 1 if this icon is used, 0 otherwise
 //
-int inspectIconFile(FTSENT * pe)
+int inspectIconMeta(FTSENT * pe)
 {
     char *point;
     char *fname;
     char app[MAXAPPLEN];
     int applen;
     char *xchar;
+    char *uchar;
+    char *endptr;
     char *dim;
     int dimlen;
     char sx[5];
@@ -193,26 +267,60 @@
     char *suff;
     int sfxn;
     int tl;
+    char *lds;
+    char *digit;
+    char *minus;
     char *generic_suffixes[] = { "-color", NULL };
+    char *legacy_dim_suffixes[] = { "16", "24", "32", "48", "64", NULL };
+    int dir = ICON_DIR_FREEDESKTOP;
+    int ext = ICON_EXT_UNKNOWN;
+    const char *special_fail_1 = "failed to interpret %s as app_WWxHH at %s\n";
 
-    // skip non-apps icons
-    if (strcmp(pe->fts_parent->fts_name, "apps") != 0)
-        return 0;
-
-    // guess app
     fname = pe->fts_name;
-    point = rindex(fname, '.');
+    point = strrchr(fname, '.');
     if (point == NULL)
         return 0;               // no extension?
-    if (strcmp(point + 1, "png") != 0)
-        return 0;               // going to load png only TODO: mention in doc
+    if (strcmp(point + 1, "png") == 0) {
+        ext = ICON_EXT_PNG;
+    } else if (strcmp(point + 1, "xpm") == 0) {
+        ext = ICON_EXT_XPM;
+    }
+    if (ext == ICON_EXT_UNKNOWN)
+        return 0;
+
+    if (strstr(pe->fts_parent->fts_name, "pixmap") != NULL)
+        dir = ICON_DIR_LEGACY;
+
+    // skip non-apps freedesktop icons
+    if (dir == ICON_DIR_FREEDESKTOP && strcmp(pe->fts_parent->fts_name, 
"apps") != 0)
+        return 0;
+
+    // guess app
     applen = point - fname > (MAXAPPLEN - 1) ? (MAXAPPLEN - 1) : point - fname;
     strncpy(app, fname, applen);
     app[applen] = '\0';
     for (tl = 0; app[tl] != '\0'; tl++)
         app[tl] = tolower(app[tl]);
 
-    // sort of generalization
+    // guess dimensions by directory
+    if (dir == ICON_DIR_FREEDESKTOP) {
+        dim = pe->fts_parent->fts_parent->fts_name;
+        dimlen = pe->fts_parent->fts_parent->fts_namelen;
+        xchar = strchr(dim, 'x');
+        if (xchar == NULL)
+            return 0;               // unknown dimensions
+        strncpy(sx, dim, (xchar - dim));
+        sx[xchar - dim] = '\0';
+        ix = atoi(sx);
+        strncpy(sy, xchar + 1, dim + dimlen - xchar);
+        sy[dim + dimlen - xchar - 1] = '\0';
+        iy = atoi(sy);
+    } else {
+        // icon other than a priory known dimensions has lowest priority
+        ix = iy = 1;
+    }
+
+    // drop known suffix
     sfxn = 0;
     while (generic_suffixes[sfxn] != NULL) {
         suff = strcasestr(app, generic_suffixes[sfxn]);
@@ -222,18 +330,52 @@
         sfxn++;
     }
 
-    // guess dimensions
-    dim = pe->fts_parent->fts_parent->fts_name;
-    dimlen = pe->fts_parent->fts_parent->fts_namelen;
-    xchar = index(dim, 'x');
-    if (xchar == NULL)
-        return 0;               // unknown dimensions
-    strncpy(sx, dim, (xchar - dim));
-    sx[xchar - dim] = '\0';
-    ix = atoi(sx);
-    strncpy(sy, xchar + 1, dim + dimlen - xchar);
-    sy[dim + dimlen - xchar - 1] = '\0';
-    iy = atoi(sy);
+    // app_48x48 legacy xpm
+    if (dir == ICON_DIR_LEGACY) {
+        uchar = strrchr(app, '_');
+        xchar = strrchr(app, 'x');
+        if (xchar != NULL && uchar != NULL && xchar > uchar) {
+            strncpy(sx, uchar+1, (xchar - uchar - 1));
+            sx[xchar - uchar - 1] = '\0';
+            ix = strtol(sx, &endptr, 10);
+            if (!(*sx != '\0' && *endptr == '\0')) {
+                msg (0, special_fail_1, app, "WW");
+                ix = 0;
+                goto end_special_1;
+            }
+            strncpy(sy, xchar + 1, app + strlen(app) - xchar);
+            sy[app + strlen(app) - xchar] = '\0';
+            iy = strtol(sy, &endptr, 10);
+            if (!(*sy != '\0' && *endptr == '\0')) {
+                msg (0, special_fail_1, app, "HH");
+                iy = 0;
+                goto end_special_1;
+            }
+            *uchar = '\0';
+        }
+    }
+end_special_1:
+
+    // app48 and app-48 legacy xpm
+    if (dir == ICON_DIR_LEGACY) {
+        digit = app + strlen(app) - 2;
+        minus = app + strlen(app) - 3; // trick for gcc-10 pseudo-intelligence
+        if (digit > app + 1) {
+            sfxn = 0;
+            while ((lds = legacy_dim_suffixes[sfxn]) != 0) {
+                if (strncasecmp(digit, lds, 3) == 0) {
+                    ix = iy = strtol(lds, &endptr, 10);
+                    if (*(minus) == '-') {
+                        *(minus) = '\0';
+                    } else {
+                        *digit = '\0';
+                    }
+                    break;
+                }
+                sfxn++;
+            }
+        }
+    }
 
     // is app already in hash?
     HASH_FIND_STR(g.ic, app, ic);
@@ -243,6 +385,8 @@
         strncpy(ic->src_path, pe->fts_path, MAXICONPATHLEN-1);
         ic->src_w = ix;
         ic->src_h = iy;
+        ic->ext = ext;
+        ic->dir = dir;
         HASH_ADD_STR(g.ic, app, ic);
     } else {
         // we already have icon with dimensions: ic->src_w, h
@@ -257,12 +401,12 @@
     }
 
     return 1;
-}                               // inspectIconFile
+} // inspectIconMeta
 
 //
-// update drawable
+// update Drawable from png file
 //
-int loadIconContent(icon_t * ic)
+int loadIconContentPNG(icon_t * ic)
 {
 
     if (!ic->drawable_allocated) {
@@ -277,7 +421,7 @@
     if (pngReadToDrawable
         (ic->src_path, ic->drawable, g.color[COLBG].xcolor.red,
          g.color[COLBG].xcolor.green, g.color[COLBG].xcolor.blue) == 0) {
-        msg(-1, "can't read png to drawable\n");
+        msg(-1, "can't read png to drawable: %s\n", ic->src_path);
         return 0;
     }
 
@@ -285,6 +429,42 @@
 }
 
 //
+// update Drawable from xpm file
+//
+int loadIconContentXPM(icon_t * ic)
+{
+    int ret;
+
+    ret = (XpmReadFileToPixmap(dpy, root, ic->src_path, &(ic->drawable),
+                &(ic->mask), NULL) == XpmSuccess) ? 1 : 0;
+    if (ret == 1) {
+        ic->drawable_allocated = true;
+    } else {
+        msg(-1, "can't read xpm to drawable: %s\n", ic->src_path);
+    }
+
+    return ret;
+}
+
+//
+// update drawable
+//
+int loadIconContent(icon_t * ic)
+{
+    int ret;
+
+    if (ic->ext == ICON_EXT_PNG) {
+        ret = loadIconContentPNG(ic);
+    } else if (ic->ext == ICON_EXT_XPM) {
+        ret = loadIconContentXPM(ic);
+    } else {
+        msg(1, "unknown icon extension: %d\n", ic->ext);
+        ret = 0;
+    }
+    return ret;
+}
+
+//
 // search app icon in hash,
 // return icon or NULL if not found
 //
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/icon.h new/alttab-1.5.0/src/icon.h
--- old/alttab-1.4.0/src/icon.h 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/icon.h 2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 icon.c definitions.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <X11/Xlib.h>
 #include <X11/Xft/Xft.h>
+#include <X11/xpm.h>
 #include <uthash.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -41,18 +42,29 @@
 typedef struct {
     char app[MAXAPPLEN];        // application name; uthash key
     char src_path[MAXICONPATHLEN];  // \0 -if not initialized or loaded from X 
window properties
-    unsigned int src_w, src_h;  // width/height of source (not resized) icon
+    unsigned int src_w, src_h;  // width/height of source (not resized) icon. 
may be 1x1 if unknown, so use it only for better icon selection, not for 
allocations
     Pixmap drawable;            // resized (ready to use)
     Pixmap mask;
     bool drawable_allocated;    // we must free drawable (but not mask), 
because we created it
+#define ICON_EXT_UNKNOWN    0
+#define ICON_EXT_PNG        2
+#define ICON_EXT_XPM        3
+    unsigned int ext;
+#define ICON_DIR_FREEDESKTOP   0   // in WxH/apps/
+#define ICON_DIR_LEGACY        1
+    unsigned int dir;
     UT_hash_handle hh;
 } icon_t;
 
 icon_t *initIcon();
 void deleteIcon(icon_t * ic);
 int initIconHash(icon_t ** ihash);
+int allocIconDirs(char ** icon_dirs);
+void destroyIconDirs(char ** icon_dirs);
 int updateIconsFromFile(icon_t ** ihash);   // load all icons into hash (no 
pixmaps, just path and dimension)
-int inspectIconFile(FTSENT * pe);   // check if file pe has better icon than 
we have in g.ic
+int inspectIconMeta(FTSENT * pe);   // check if file pe has better icon than 
we have in g.ic
+int loadIconContentPNG(icon_t * ic);
+int loadIconContentXPM(icon_t * ic);
 int loadIconContent(icon_t * ic);   // update drawable
 icon_t *lookupIcon(char *app);  // search app icon in hash
 bool iconMatchBetter(int new_w, int new_h, int old_w, int old_h);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/pngd.c new/alttab-1.5.0/src/pngd.c
--- old/alttab-1.4.0/src/pngd.c 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/pngd.c 2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Reading PNG into Drawable.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -250,6 +250,7 @@
     fclose(infile);
     if (!img.data || img.width == 0 || img.height == 0) {
         fprintf(stderr, "error loading png data\n");
+        pngFree(&img);
         return 0;
     }
     if (debug > 0)
@@ -259,6 +260,7 @@
     pad = 32;
     if (!xdata) {
         fprintf(stderr, "xdata malloc error\n");
+        pngFree(&img);
         return 0;
     }
     ximage =
@@ -267,6 +269,7 @@
     if (!ximage) {
         fprintf(stderr, "error creating ximage\n");
         free(xdata);
+        pngFree(&img);
         return 0;
     }
     ximage->byte_order = MSBFirst;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/pngd.h new/alttab-1.5.0/src/pngd.h
--- old/alttab-1.4.0/src/pngd.h 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/pngd.h 2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 pngd.c definitions.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/randr.c new/alttab-1.5.0/src/randr.c
--- old/alttab-1.4.0/src/randr.c        2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/randr.c        2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Interface to XRANDR
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -186,8 +186,7 @@
     if (no < 1) {
         msg(0, "randr didn't detect any output\n");
         *multihead = false;
-        if (oq != NULL)
-            free(oq);
+        free(oq);
         return false;
     }
     if (no == 1) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/rp.c new/alttab-1.5.0/src/rp.c
--- old/alttab-1.4.0/src/rp.c   2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/rp.c   2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Interface with Ratpoison window manager.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/util.c new/alttab-1.5.0/src/util.c
--- old/alttab-1.4.0/src/util.c 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/util.c 2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Helper functions.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -25,6 +25,9 @@
 extern int scr;
 extern Window root;
 
+XErrorEvent *ee_ignored;
+bool ee_complain;
+
 // PUBLIC:
 
 //
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/util.h new/alttab-1.5.0/src/util.h
--- old/alttab-1.4.0/src/util.h 2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/util.h 2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 util.c definitions.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -47,8 +47,8 @@
 #define MAXNAMESZ   256
 #endif
 
-XErrorEvent *ee_ignored;
-bool ee_complain;
+extern XErrorEvent *ee_ignored;
+extern bool ee_complain;
 
 // values for pixel composite transformations
 // which are constant per entire image
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/win.c new/alttab-1.5.0/src/win.c
--- old/alttab-1.4.0/src/win.c  2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/win.c  2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Interface with foreign windows common for all WMs.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify
@@ -221,9 +221,7 @@
             n += w*h;
             continue;
         }
-        msg(1, "Trying icon at position %lu (%dx%d)\n", n, w, h);
         if (best == 0 || iconMatchBetter(w, h, best_w, best_h)) {
-            msg(1, "Icon is better\n");
             best = n;
         }
         n += w*h;
@@ -233,6 +231,7 @@
         //free(prop); better don't
         return 0;
     }
+    msg(1, "using %dx%d %s icon for %lx\n", w, h, NWI, wi->id);
 
     image32 = malloc(best_w * best_h * 4);
     CompositeConst cc = initCompositeConst(g.color[COLBG].xcolor.pixel);
@@ -338,16 +337,26 @@
                  || iconMatchBetter(ic->src_w, ic->src_h,
                                     wi->icon_w, wi->icon_h))
                 ) {
-                msg(0, "using png icon for %s\n", tryclass);
+                msg(0, "using file icon for %s\n", tryclass);
                 if (ic->drawable == None) {
                     msg(1, "loading content for %s\n", ic->app);
                     if (loadIconContent(ic) == 0) {
-                        msg(-1, "can't load png icon content\n");
+                        msg(-1, "can't load file icon content: %s\n", 
ic->src_path);
                         continue;
                     }
                 }
+                // for the case when icon was already found in window props
+                if (wi->icon_allocated) {
+                    XFreePixmap(dpy, wi->icon_drawable);
+                    /*
+                    if (wi->icon_mask != None) {
+                       XFreePixmap(dpy, wi->icon_mask);
+                    }
+                    */
+                    wi->icon_allocated = false;
+                }
                 wi->icon_drawable = ic->drawable;
-                wi->icon_mask = 0;
+                wi->icon_mask = ic->mask;
                 ret = 1;
                 goto out;
             }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/alttab-1.4.0/src/x.c new/alttab-1.5.0/src/x.c
--- old/alttab-1.4.0/src/x.c    2019-05-01 18:39:58.000000000 +0200
+++ new/alttab-1.5.0/src/x.c    2020-07-23 10:24:20.000000000 +0200
@@ -1,7 +1,7 @@
 /*
 Interface with foreign windows in raw X11.
 
-Copyright 2017-2019 Alexander Kulak.
+Copyright 2017-2020 Alexander Kulak.
 This file is part of alttab program.
 
 alttab is free software: you can redistribute it and/or modify


Reply via email to