commits
Newer Firefox versions use this for notifications so we need to map
them on top with a thin border, but not raise them so they don't
steal focus.
redraw_frame conditionally calls recalc_frame but checks the frame
config first, so we need to adjust the frame before redrawing.
This helps VLC redraw properly after coming out of fullscreen mode.
$ progman
progman: X error (0): BadWindow (invalid Window parameter)
Oh no. This the bad window parameter is in fact one of the
XSetWMNormalHints() calls. Here's what happens:
launcher_setup()
launcher_reload()
XSetWMNormalHints(dpy, launcher_win, hints);
launcher_win = XCreateWindow()
Let's move the XSetWMNormalHints() after the XCreateWindow() so that
everybody can be happy and live in peace.
This also sets things up to make it easy to add a binding for
resizing from anywhere like alt+mouse3 that some other WMs do.
Rather than lowercasing the key and later trying to uppercase the
first character if XStringToKeysym fails, retain the original case
and use strcasecmp while checking for modifiers. This allows
complex keys like XF86AudioPlay to get parsed properly.
Though we need to retain lowercasing for single-character keys
because "Win+T" was previously getting parsed as Mod4+t, and if the
user wanted an actual capital T they would do Mod4+Shift+T.
Do pixmap scaling on the fly, but because the title bar icons look
too big to 2x, use the hidpi icons that are more like 1.5x icons.
When walking the list of clients, this was relying on pp (previous
non-iconified client) being set to make its next window the new
client.
If we only have iconified clients in the list, pp will never be set,
so the new client becomes the focused list head.
If we clicked in the corner of the screen, mapping will move the
launcher window to fit on the screen so update x/y.
Also don't highlight by default because our cursor won't necessarily
be at the first entry now, but also because accidentally
right-clicking on the root shouldn't just launch the first thing on
the list.
Helps Audacious raise its playlist when clicking on the main window
Fixes GIMP's initial splash screen
We should only get here if a window was iconified and thus created
an XftDraw, but XftDrawDestroy(NULL) causes a seg fault so make
extra sure we don't do that.
We're zeroing the c struct after allocating so all of these are
already None/0/NULL.
This was only being done in del_client so it was leaking each time a
window was iconified.
Instead of using XSetErrorHandler to switch to an empty function,
keep it at handle_xerror and use a global flag that determines
whether to ignore errors. This allows functions to increment and
decrement the flag counter without affecting their callers.
Atom code was ignoring X errors and then turning them back on, but
del_client needs them ignored for the duration of the function. Now
Atom can ignore them without turning them back on while called from
del_client.
This keeps the default of right click bringing up the launcher by
default, but also adds mouse wheel buttons (4 and 5) to switch to
the next and previous desktops by default.
A "launcher" action is added to support this, which means it can
also be brought up from a keyboard binding so make launcher_show()
handle this properly.
We're supposed to XFree() the result of XGetWMHints but we need it
to know a client's icon pixmap if we need to redraw it, so keep it
around and XFree() it just before we get new hints.
Also track whether we drew our own scaled pixmaps so we can properly
XFreePixmap() them before changing them to something else or
destroying the client.
If the client wants to start iconified, handle it appropriately.
Audacious' Winamp style GUI configures its playlist window with:
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DIALOG,
_KDE_NET_WM_WINDOW_TYPE_OVERRIDE, _NET_WM_WINDOW_TYPE_NORMAL
So only checking/storing the first one does not find that this
window is not supposed to have decorations.
Audacious uses this for its Winamp style GUI
Store the original argv[0] and during restart, cleanup and resign as
the window manager, then execlp(argv[0]).
This will help things like compton not draw shadows under them.
We're not sharing anything with any external programs so there's
nothing to make common anymore.
Move the action taking out of the keyboard code and allow it to be
shared with the launcher.
Add a "quit" action which can now be used by both, and add it to the
bottom of the default launcher menu.
This lets us drop the dependency on Gtk and avoids having to shell
out to an external program.
Admittedly the new launcher window has a very Xt feel to it, but
maybe we can spruce it up with some button bevels or something
later.
This avoids having to specify any default keybindings in code and if
the user has their own config file, no longer requires them to
override the default keybindings to get rid of them.
This seems to be what most programs expect when they pass position
hints.
The single-pixel frame seems uncommon in Windows dialogs, so prefer
the normal width frame with no resize handles.
$ progman
progman: X error (0): BadWindow (invalid Window parameter)
Oh no. This the bad window parameter is in fact one of the
XSetWMNormalHints() calls. Here's what happens:
launcher_setup()
launcher_reload()
XSetWMNormalHints(dpy, launcher_win, hints);
launcher_win = XCreateWindow()
Let's move the XSetWMNormalHints() after the XCreateWindow() so that
everybody can be happy and live in peace.
Rather than lowercasing the key and later trying to uppercase the
first character if XStringToKeysym fails, retain the original case
and use strcasecmp while checking for modifiers. This allows
complex keys like XF86AudioPlay to get parsed properly.
Though we need to retain lowercasing for single-character keys
because "Win+T" was previously getting parsed as Mod4+t, and if the
user wanted an actual capital T they would do Mod4+Shift+T.
If we clicked in the corner of the screen, mapping will move the
launcher window to fit on the screen so update x/y.
Also don't highlight by default because our cursor won't necessarily
be at the first entry now, but also because accidentally
right-clicking on the root shouldn't just launch the first thing on
the list.
Instead of using XSetErrorHandler to switch to an empty function,
keep it at handle_xerror and use a global flag that determines
whether to ignore errors. This allows functions to increment and
decrement the flag counter without affecting their callers.
Atom code was ignoring X errors and then turning them back on, but
del_client needs them ignored for the duration of the function. Now
Atom can ignore them without turning them back on while called from
del_client.
This keeps the default of right click bringing up the launcher by
default, but also adds mouse wheel buttons (4 and 5) to switch to
the next and previous desktops by default.
A "launcher" action is added to support this, which means it can
also be brought up from a keyboard binding so make launcher_show()
handle this properly.
We're supposed to XFree() the result of XGetWMHints but we need it
to know a client's icon pixmap if we need to redraw it, so keep it
around and XFree() it just before we get new hints.
Also track whether we drew our own scaled pixmaps so we can properly
XFreePixmap() them before changing them to something else or
destroying the client.