[news] TWM -- Revised Edition
Eeri Kask <[email protected]> Tue, 30 Sep 2008 19:20:25 +0200
| Newsgroups | gmane.comp.freedesktop.xorg,gmane.comp.xfree86.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello TWM users,
Having tweaked the TWM since last year to turn it into something
contemporary in look and handy in function, today as a landmark of
approaching zero items in my own kept TWM bugs-, todo- and wish-list may
I use the moment to present this humble effort which has kept me pretty
busy in the leisure time since then.
(*) Initially significant emphasis went into introducing and finetuning
Xft truetype font support which is now a per-screen startup configurable
feature. If e.g. the Xft subsystem is not available TWM automatically
falls back to X11 core font renderer. (If started with '-truetype' one
can turn Xft off intentionally.)
X11 core font names and Xft font names can be used arbitrarily
intermixed in .twmrc as each font name is first attempted to resolve as
XLFD name and only if this fails, then as Xft name.
(*) Further, sloppy focus is now seamlessly integrated into TWM at its
most core. In the same sweep the icon manager highlighting now follows
focus and not mouse, making a lot sense for keyboard users caring less
about mouse.
(*) Keyboard-aided mouse navigation has been enhanced as well. It is a
high priority to control TWM comfortably by keyboard (with the exception
of 'f.move', 'f.resize'), so the functions
f.warpnext, f.warpprev
f.warpring
f.forwiconmgr, f.backiconmgr, ...
f.nexticonmgr, f.previconmgr
f.warpto "", f.warptoiconmgr ""
all having to do with mouse warping along client windows have been
overworked to expose kind of a unified, consistent behaviour (e.g. all
tied to 'WarpUnmapped', and all respect originally only by 'window-ring'
saved mouse location coordinates).
(*) Invented is 'f.swapiconmgrentry' as a simple mechanism for run-time
icon manager manual sorting which now leads to arbitrary
client-to-client mouse travelling by at most two "keystrokes", using the
icon manager as a switchboard.
(*) There is Xinerama support which can be turned off by '-xinerama'
command line parameter leading to TWM treating the logical screen at
full size (but possibly loosing icon managers, icon regions and client
windows into dead areas).
Into this improvement category belongs 'RandomPlacement' algorithm which
got a preliminary step first looking for an empty area on screen large
enough to fit the window prior to placing it blindly at some 'random'
location.
(*) The '-v' command line option gives some more info on startup and on
'f.identify'.
(*) Last but not least several old bugs have been corrected: most
notably related to multiscreen configurations and to 'f.focus'; and icon
manager navigation functions no longer should occasionally unexpectedly
refuse service, except if rendered dysfunctional by 'NoIconManagers'.
(*) A script of all enhancements (at varying level of detail) is
attached as "NEWS.RevisedEdition" and the man page is uptodate. (If one
agrees to read one entry in the man page, the 'IconManagerGeometry' is
the item worth a look.)
Keeping up the tradition of X development not to impose policy and even
less taste all visual/functional enhancements are not only tunable but
the .twmrc file if kept as is, leads to no change in TWM traditional
look and function with the exception of (1) coloured icons if provided
by clients; and (2) the semantics of 'WarpCursor' is slightly broadened:
in addition now automatic warping into transient windows of focused
clients occurs if they get mapped.
Though, the whole effort has lead to increase in TWM executable file by
a factor of circa 1.2 which is very unfortunate, the foremost
contributors being (referencing the x86_64 platform)
Xft (by ~ 8 Kbytes)
Xinerama (~ 8 Kbytes)
Xrandr (~ 4 Kbytes)
sloppy focus (~ 4 Kbytes)
visual appearance improvements altogether ~ 12 Kbytes
Concluding, here are presented various TWM enhancement proposals; anyone
caring I am happy to invite to comment/discuss/review these, and
anything related how to further finetune/improve TWM ... as an X11
window- (not necessarily an office desktop-) manager. :-)
Let me here in retrospect express my sincere thank you to all guys
having helped to chase bugs and figure out better ways in making TWM better,
Eeri Kask
P.S. To automatically compile, run
http://www1.inf.tu-dresden.de/~ek1/TWM-Tweaked.sh
_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg
NEWS.RevisedEdition
(text/plain, 29.9 KB)
TWM -- Revised Edition
======================
Each of the twm.man.diff?? patches belongs to the corresponding
patchset diff??.twm-1.0.4.*.
(0) twm.man.diff00
This patch documents previously undocumented twm functionality
(most items were commented out). Most notable are f.warpnext,
f.warpprev.
Patchsets
diff01.twm-1.0.4.MyFont_ChangeGC
diff02.twm-1.0.4.MyWindow
diff03.twm-1.0.4.TWM_USE_XFT
implement per-screen configurable Xft-truetype font support.
(1) diff01.twm-1.0.4.MyFont_ChangeGC
First, few loose colour pairs denoting fore/back (twm.h, menus.h,
iconmgr.h) are coupled into ColorPair-datastructure, necessary for
later font rendering calling interface.
Second, the functionality of MyFont_ChangeGC() in downshifted into
MyFont_DrawString() and MyFont_DrawImageString() respectively and
this function itself is removed. The calling interface of the
MyFont_Draw...() functions is adapted accordingly.
(2) diff02.twm-1.0.4.MyWindow
Twm own windows (menus, icons, iconmanagers, title bars,
info-/sizewindow) which later will feature Xft-font rendering are
enclosed into the 'MyWindow' datastructure to encapsulate the
font-drawing target drawable: for core fonts or for Xft-fonts.
The calling interface of MyFont_DrawString() and
MyFont_DrawImageString() is adapted accordingly.
(3) diff03.twm-1.0.4.TWM_USE_XFT
This patchset introduces the EnableXftFontRenderer per-screen
keyword. The '-truetype' command line option disables Xft usage,
falling back to core fonts. Further, if Xft is not available,
fallback to core fonts occurs as well. If during runtime core-font
or Xft-font renderer is to be used is determined solely by the
Scr->use_xft variable.
As XftDrawCreate() in libXft may return a NULL-pointer, the sole
purpose of the wrapper function MyXftDrawCreate() is to check this
and output a warning. MyXftDrawDestroy() does the cleanup. As the
Xft-documentation apparently doesn't treat this NULL-pointer
issue, the pointer is passed unaltered to XftDrawString8()
delegating the responsibility not to crash twm to that function.
The function MyFont_DrawShapeString() draws text (core font or
Xft-font) onto a depth-1 pixmap to be used later as
underground/shapemask in Shape-extension-based transparent text
rendering in icons and icon managers.
The MyFont_Draw...Ellipses() functions are prepared for
abbreviated text drawing, which ends with "...".
An aspect to be noted is, Xft-based rendering occurs with
alpha-blending against the existing drawable background. This has
the consequence that the background has to be cleared prior to any
drawing in order to avoid text smearing which occurs on repeated
Expose events. Therefore, in some cases the original
MyFont_DrawString() is replaced by MyFont_DrawImageString() and in
other cases preceded by XClearArea(). Affected is events.c
HandleExpose() mostly.
The core-font vs. Xft-font name in .twmrc is resolved as follows.
The font name is first assumed to be a core font and its eventual
alias is resolved by XGetFontProperty() using XA_FONT. If this
resolving succeeds, the 'core' font is opened using
XftFontOpenXlfd(). Otherwise the font name is assumed Xft-name,
and XftFontOpenName() is called.
Xft-support is included by -DTWM_USE_XFT gcc option.
(4) diff04.twm-1.0.4.TWM_USE_SPACING
Pixel-based text spacing is replaced by font-size-based text
spacing. This ensures smaller baseline skips and left/right
margins for small text sizes and vice versa. This spacing is
independent of core- or Xft-font usage. This feature can be
enabled by -DTWM_USE_SPACING.
(5) diff05.twm-1.0.4.TWM_USE_SLOPPYFOCUS
First, the screen-based focus state variables "Scr->Focus" and
"Scr->FocusRoot" are made global as nothing seems justifying them
to be screen based and so simplifies understanding of twm focus
management and cleans code.
Second, few 'f.focus'-related bugs are corrected, e.g.
WarpToScreen() and Execute(): the first not working at all, the
latter executes the Execute() on the screen with f.focus'ed
client and not where the mouse is. This is extremely
counterintuitive. FindPointerScreenInfo() now finds the screen
where the mouse is.
The F_FOCUS handling in ExecuteFunction() in menus.c is shifted
into a dedicated function FocusOnClient() to be used elsewhere as
well.
This patchset introduces the 'SloppyFocus' keyword and the
'f.sloppyfocus' function, and implements the sloppy focusing of
client windows: the client is not unfocused while leaving. It is
unfocused only if entering some client which is going to accept
focus (according to ICCCM).
A client 'Tmp_win' accepting focus means the boolean expression
(Tmp_win->wmhints == NULL) || (Tmp_win->wmhints->input == True)
|| (Tmp_win->protocols & DoesWmTakeFocus)
is evaluated to 'true'.
If the client is not going to accept focus, the focus remains in
the previous window (or, if in the icon manager, the focus is set
to 'PointerRoot'). If in the icon manager and the highlighted
client is iconified, the focus is set to 'PointerRoot' as well (in
both cases not leaving the 'SloppyFocus' state, so the next
focusable client grabs focus again).
Most affected functions are HandleEnterNotify() and
HandleLeaveNotify(). The 'Focus' global pointer always points to
the client having focus or is NULL if no client is expicitly
assigned focus by XSetInputFocus(). The 'FocusRoot' is never
'true' if some client is f.focus'ed and blocks executing some code
segments accordingly. Here SloppyFocus, which largely operates
like f.focus, while 'true' unblocks most of these code segments
(mostly the one in HandleEnterNotify()), so enabling focus
assignment on entry into some client. So 'FocusRoot' can be 'true'
while SloppyFocus is 'true', as long as no focusable client is
entered. It is intension that 'f.sloppyfocus' always first sets
'FocusRoot' to 'true' (and sets X server focusing to 'PointerRoot'
mode) so withdrawing focus out of some client if executed on a
root window (though, if executed not on a root window e.g. by a
twm keybinding, then while releasing the bound keypress an Enter
event is generated for that client under mouse, so setting 'Focus'
to that client and 'FocusRoot' to 'false').
Finally, the window border, title bar highlight and icon manager
highlighting reflect the following. (1) The window border
reflects Enter/Leave events (into/out of client windows, or
respective icon manager entries label-windows), irrespective of
SloppyFocus, f.focus, or client focusability. (2) The title bar
is highlighted by FocusIn/FocusOut events twm catches (or twm sets
them in cases these events are not expected, like focusing by
SendTakeFocus, or in PointerRoot mode). (3) The icon manager
highlighting reflects the twm's believing where the focus should,
be irrespective where the mouse is (esp. in SloppyFocus mode);
e.g. unfocusable windows are not highlighted in the icon manager.
As a rule the icon manager and the corresponding title bar
highlighting should coincide (attn: 'NoTitleFocus' disables icon
manager focus redirecting, so no entries in iconmanager are ever
highlighted then).
Last but not least, 'SloppyFocus' obsolates 'NoTitleFocus' for the
time while 'true'.
To enable sloppy focus, use -DTWM_USE_SLOPPYFOCUS compiler flag.
(6) diff06.twm-1.0.4.IconMgrCollapseFix
If configuring some icon manager in .twmrc to have multiple
columns, then moving or resizing that icon manager window and
finally a new client is created or some destroyed (so that
PackIconManager() is executed) one observes a kind of iconmanager
window horizontal collapsing. Seemingly this bug is known as in
EndResize() in resize.c and the 'savewidth' variable in
PackIconManager() function probably are attempts to deal with this
issue. Further investigation disclosed the 'cur_rows' and
'cur_columns' iconmanager member variables are never explicitly
initialised having arbitrary initial values on first referencing
in PackIconManager(). It looks like this leads to that said
iconmanager window gradual collapse. This patchset cleans up this
mess (i.e. provides a better solution).
(7) diff07.twm-1.0.4.Fixes
This patchset only contains some of the obvious bugs in twm,
various others are silently dealt with in appropriate other
patchsets.
(a) There is a missing 'break' leading to unintended 'switch'
fallthrough in gram.y.
(b) The 'dpy' call parameter is removed from I18N_FetchName() and
I18N_GetIconName() calling interface as this is a global variable
anyway and passing this into these only functions is pointless.
(c) XShapeSelectInput() is called consequently twice in
AddWindow() with no apparent reason.
(d) The Zoom() function includes 'unsigned' integers in an
arithmetical operation assuming signed-integer arguments. (Leading
to nonsense in icon zooming drawing; how this bug could survive 20
years?)
Iconify() and DeIconify() are slightly reordered.
(e) I18N_FetchName(), I18N_GetIconName() very probably leak
memory, especially the latter (not setting 'iconname' to NULL if
it fails, missing XFree(text_prop.value); etc). Both are
cleaned up.
(f) The ":menu" pixmap (which is created only once in twm
lifetime) can easily have different uses, like be used on the
title bar with a huge font, and in a menu having a small font.
Now using the same pixmap tuned for the large font size is wrong
in the case of a menu. So CreateMenuPixmap() had to be rewritten
with this in mind.
(g) SetFocus() in util.c didn't check Scr->Focus being NULL and
crashed twm in '#ifdef TRACE' branch while performing f.restart.
(h) F_CUT and F_CUTFILE included obvious buffer overflow holes.
(The purpose of these functions is yet to be figured out; at first
sight it looks like alien garbage ... in the sense that, why
wasn't that code snippet prepended with XOpenDisplay() and moved
out into a stand-alone application, and then run by 'f.exec'?)
(i) CreateIconManagers() had potential buffer overflow holes
caused by sprintf().
(j) Identify() shows the borderwidth 'bw' which is always '0' for
all clients all times, as this borderwidth is always kept zero,
as can be seen in AddWindow().
(k) DrawIconManagerBorder() may sometimes draw to some other
screen as pointed to by 'Scr' (look at 'UnHighLight_win' in
events.c in HandleEnterNotify()!). It is essential to use the
saved 'scr' iconmanager member variable as reference for that
drawing.
(l) ExecuteFunction() should only in few selected cases (F_MOVE,
F_RESIZE) execute XGrabPointer() with 'confined_to' set to
Scr->Root on entry. In a multiscreen environment this leads to
mouse warpings to some other screen where some random X-event
happens without an apparent reason for the twm user (e.g.
client-initiated 'iconify').
(m) Twm suppressed printing out of most X-protocol errors in
TwmErrorHandler(). Often these are generated by having events of
a dead client in the twm X-event pipeline. Now introduced
DiscardWindowEvents() should throw these out in
RemoveIconManager(), HandleDestroyNotify() and
HandleUnmapNotify().
This X-error printout is enabled again without restrictions and
all occurrences of these errors should be considered twm bugs
which are to be investigated.
(8) diff08.twm-1.0.4.Appearance
(a) If the iconmanager layout specification contains 'North' or
'East' then the iconmanager while growing extends to the left or
top (iconmanager "gravity" against to the root window is at some
other as the default top-left corner). This functionality is
essential for 'horizontal' icon managers, e.g. at the screen
bottom to not extend off screen if rows are appended (and then
automatically shrink down if rows are removed). Principal code
is in InsertInIconManager() (list reversing) and SortIconManager()
(sorting order predicate inversion).
(b) If the 'columns' parameter in icon manager layout
specification is negative, extra entries are prepended (not
appended) to the linked list. This also affects the
ascending/descending icon manager alphabetical sorting.
Principal code is in PackIconManager().
(c) Iconmanagers now have ClassHints and can be configured by
.twmrc as usual clients.
(d) Iconmanager "iconify knob" has now sizes 11x11 (original
size), 13x13, 15x15, 17x17, 19x19, 21x21; and the size to be used
is chosen proportional to iconmanager font height during icon
manager creation. Global variables 'iconifybox_width',
'iconifybox_height', 'iconmgr_textx' must be now local to 'Scr'.
(e) Icon manager entry iconify-knobs and title bar buttons pixmaps
are respective window background pixmaps now, therefore no Expose
events are needed for drawing them, so HandleExpose() could be
simplified.
(f) The twm-client list and the ring-list are backwards sorted in
respect to the (unsorted) icon manager list order. This leads to
confusion if f.warpnext and f.warpring "next" highlight icon
manager entries which run in reversed order (bottom up or right to
left). Elements in both first lists are prepended, icon manager
elements are appended to the list. Now all elements in both lists
are sorted accoring to 'Scr->iconmgr.reversed' being 'true'
(prepended) or 'false' (appended).
(g) If the value given to 'FramePadding' is greater than TitleFont
height (which only becomes apparent after font loading), this
value is treated as title bar height and the actual value for
'FramePadding' is calculated as the half difference of the title
bar height and TitleFont height. This allows to specify title bar
height in pixels exactly. (If 'FramePadding' specified in .twmrc
is not greater than TitleFont height, this recalculation is not
performed.)
(h) The 'DefaultFont' keyword is introduced (used by Infowindow).
(i) Info-/Sizewindows now have border width of Scr->BorderWidth
and border color of Scr->BorderColor.
(j) Menu titles are rendered using the Scr->TitleBarFont.
(k) Infowindow of f.identify displays some client window property
values if twm is started with '-v'. (f.version shows the focus
window and 'revert-to' ... to chase clients which set focus to
None.)
(9) diff09.twm-1.0.4.TitleHighlight
This patchset introduces
TitleHighlightForeground
TitleHighlightBackground
TitleButtonForeground
TitleButtonBackground
RoundedTitle
BorderTile
.twmrc keywords. The first two are the BorderTileForeground,
BorderTileBackground counterparts and specify the title bar focus
highlight pixmap foreground, background colors. Button colours do
the same to titlebar buttons (the button border is painted in
button foreground color; alternatively one can set the border
width to zero and enlarge the button bitmap accordingly).
'RoundedTitle' can be seen as "SqueezeTitle-Light" setting 3x3
shape (bounding, and if borderwidth > 0 then for clipping) bitmaps
to the upper left/right corners of the frame window.
InitTitlebarCorners() initialises the shape pixmaps and
SetFrameShape() sets the shape on frame-window resize etc. The
upper corners of menus are shaped only if the first entry is of
type 'F_TITLE'. (And, of course, client windows not having the
title bar are not shaped as well.)
'BorderTile' is the 'TitleHighlight' pixmap counterpart: the
xbm-pixmap for client window frame borders.
All above parameters default to their usual values.
(10) diff10.twm-1.0.4.Ellipses
Text on window titlebars, iconmanager entries and icon labels is
cut off not to exceed some maximum length apparent from the
particular context and become the string "..." appended depicting
this cutoff. E.g., if icon regions are specified in .twmrc, then
the maximum area width of a grid cell over all given icon regions
is determined and no icon label will be wider than this value.
This ensures the icon placing algorithm always succeeds in finding
a grid location for the icon and doesn't place the icon randomly
at the mouse location arbitrarily on the root window stretching
from the left screen edge to the right. In HandleExpose() in
events.c all occurrences of MyFont_Draw..String() are replaced by
MyFont_Draw..StringEllipses() accordingly.
(11) diff11.twm-1.0.4.ShapedIcons
Introduces 'IconBitmapColor' keyword to determine the foreground
color for depth-1 pixmaps for icons instead of using the
'IconForeground'. Further, if some client provides a color icon in
WM_HINTS, this is used by XCopyArea() instead of historical
XCopyPlane() which used to work for depth-1 pixmaps.
Further, 'ShapedIconPixmaps' boolean variable determines if the
icon area in the icon window gets a bounding shape (assuming the
client provides a shape pixmap in WM_HINTS). For clients providing
depth-1 icon pixmap this same pixmap is used for bounding shape.
'ShapedIconLabels' (translation) geometry variable activates the
icon label text shaping. First, the text is drawn onto a shape
bitmap (depth-1). Then if the translation argument is not "+0+0"
then the shape bitmap is copied onto itself appropriately for
the specified amount of x-shift and y-shift. This bitmap is used
as bounding-shape for the text area of the icon. The shifted area
is painted in 'IconBackground', influencing the text (which is
drawn by 'IconForeground') contrast and readability against the
root window. SetIconShapeMask() sets both bounding shapes: for
the icon pictogram and for the icon label text.
(12) diff12.twm-1.0.4.ShapedIconManager
'ShapedIconManagerLabels' is the icon manager counterpart of
'ShapedIconLabels'.
In DrawIconManagerBorder() the 'FilledIconManagerHighlight' draws
a filled background as iconmanager highlighting and not a
rectangular outline.
The shape masks are drawn directly onto the iconmanager
twm-window-frame denoted 'ip->twm_win->frame'. Alternatively one
could draw them onto iconmanager client window 'ip->twm_win->w'
and rely on twm's HandleShapeNotify() to copy them to the 'frame'
but this gives nothing except a huge copy overhead. The only
cosmetic drawback is, SetFrameShape() erases this shape mask and
after F_MOVE'ing the iconmanager these shapes need to be painted
anew in ExecuteFunction().
Finally, to speedup iconmanager Enter/Leave events handling, these
events are ignored (not selected at all) in AddWindow() for the
'tmp_win->frame' and 'tmp_win->w' windows of the corresponding
iconmanager clients. Processed are Enter/Leave events only
into/out-of iconmanager client-label windows; which is enough.
Therefore unnecessarily repeated iconmanager painting by
ActiveIconManager() and NotActiveIconManager() can be avoided
which is otherwise caused by entering the above 'frame' and 'w'.
Though, as a downside the 'AutoRaise' of iconmanagers needs
special treatment in HandleEnterNotify() now; which is far less
costly as the unnecessary (shape, etc) painting otherwise.
(13) diff13.twm-1.0.4.XUrgency
The RaiseInfoWindow() contains now code which is extracted from
Identify() in order to generally use Infowindow regardless of
purpose (f.version, f.identify). Now Infowindow shows the client
window name if this client sets the XUrgency flag in WM_HINTS.
This Infowindow is positioned across the title bar of the client
(or at the top-left corner of the screen if the client is
iconified).
Apart from the purpose above this mechanism can be successfully
(mis-)used by the client to communicate a message to the twm user
by XUrgency: first set the window title to some message text, then
raise XUrgency, and then restore the original title text again.
The message appears above the client window title bar in the
infowindow.
(14) diff14.twm-1.0.4.NoWindowRing
Simple usage extension of WindowRing: include into window ring
anything but clients in 'NoWindowRing'. Though, if 'WindowRing'
is specified in .twmrc, then this variable here is void.
(15) diff15.twm-1.0.4.NoWarpCursor
'WarpCursor' semantics is moderately extended: not only is the
mouse warped into the client on deiconifying but on client mapping
as well. Though, this warping is disabled if some client has
'f.focus' activated. Not only is it a security issue but it is not
apparent what to do with f.focus in such a case generally, e.g.
(1) release f.focus, (2) transfer f.focus to the client to be
warped into, (3) restore f.focus or not after disappearing of this
client (needs implementing of focus history mechanism); or any
combination of these. Being a complex issue the most reasonable
seems to do nothing automatically in this case, justifying this
with the fact that the user having intentionally activated f.focus
now it is up to him to manually unfocus that client first in order
to restore the 'WarpCursor' auto-warping functionality.
Finally and most importantly, 'WarpCursor' or 'NoWarpCursor', each
of these activate automatic warping into 'local' transient
windows which means, that happens if and only if that transient
window's WM_TRANSIENT_FOR points to the client having iconmanager
highlight or having focus; or if the transient window is in the
same 'window group' as the client being highlighted or having
focus.
'NoWarpCursor' activates warping into all clients but these listed
here. If 'WarpCursor' is also specified, this list here is ignored.
(16) diff16.twm-1.0.4.Fmaximize
A simple extension of f.fullzoom: enlarges the client to
preferrably (up to ConstrainSize()) cover 100% of the root window;
leaving twm-generated titlebar and frame window borders out of the
visible screen area. The top-left pixel of the client is always
at (0,0).
(17) diff17.twm-1.0.4.RandomPlacement
Btw. not being 'random' placing at all this patchset doesn't
change that fact either but first tries to find an empty screen
area to be large enough to fit the client without covering some
other client, and only if this fails then falls back to the
original placing algorithm. The area search looks for a 'best fit'
and 'next to best fit' area: the first is slightly larger than the
client so leaving some empty room on each side, the latter may
result in edge-to-edge placement in respect to some other client.
The client windows are filled in left-to-right and top-bottom
order across the screen. The FindEmptyArea() runs recursively and
takes rectangle-info (4x4 integers plus pointer) from the stack as
'auto' variable on each iteration.
Some toolkits put transient windows at arbitraty locations not
checking if they are fully visible on the screen, so twm now
checks that (and tries to make them 100% visible).
(18) diff18.twm-1.0.4.TWM_USE_XINERAMA
Xinerama support includes:
(a) The xinerama-specific X11 code is only in twm.c in setting up
the tile list.
(b) Previously existing geometry-checking inlined code is shifted
into EnsureRectangleOnScreen() or EnsureRectangleOnTile()
functions.
(c) Twm menus, icon regions, icon managers, info-/sizewindows are
ensured to not fall in dead areas by a minimum possible effort.
Menus are not split across tiles. Client windows are first
attempted to put on tiles having already group members or
WM_TRANSIENT_FOR 'relatives', only then they are put on the tile
containing the mouse. If a 'reference' client spans several tiles,
the one is chosen containing the most pixel area of that client.
(d) Xinerama zoom: clients are usually zoomed across these
physical screen tiles which they already intersect and not extend
to others, with few obvious exceptions to that rule.
The algorithm is window edge based and first determines the
rectangular convex hull in terms of existing tiles including the
client window pixel area. This area is usually (but not always)
larger than the client pixel area. Then this rectangular area is
shrunk as much as possible to reduce (and not introducing) dead
areas enclosed. If the client is initially (partially) outside of
all physical tiles, it is brought to the nearest (in euclidean
sense) tile.
This approach should hopefully survive a variety of different
geometrical and topological physical screen tile arrangements, at
least most reasonable cases.
There are few (currently pixel-based) parameters with hard-coded
values determining how large slits between tiles are not
considered dead areas. (It is hoped usually there are no slits in
practice so this is more of a "theoretical" concern.)
(19) diff19.twm-1.0.4.TWM_USE_XRANDR
The 'RestartOnScreenChangeNotify' handler first unzooms all
windows on all screens as their location and size data is lost
during f.restart. All tile housekeeping is done by code
introduced by Xinerama support.
(20) diff20.twm-1.0.4.SwapIconMgrEntry
In order to better utilise twm for keyboard-driven
focus/mouse-navigation across client windows some manual sorting
of icon manager entries is essential. The 'f.swapiconmgrentry'
function swaps two consecutive elements in the WList* chain of the
corresponding icon manager. If 'SortIconManager' is true, this
manual sorting makes no sense (is disabled).
(21) diff21.twm-1.0.4.Warp
Twm features mouse/focus warping at least in the following
ways:
(a) f.warpnext, f.warpprev
(b) f.warpring "next", f.warpring "prev"
(c) f.forwiconmgr, f.backiconmgr
(d) f.nexticonmgr, f.previconmgr
(e) f.warpto, f.warptoiconmgr
(f) WarpCursor
(missing is f.warptoscreen not being client window/focus related)
Until now of these only f.warpring tracks and utilises current
mouse coordinates in the client; in all other cases the mouse is
warped to some uncomfortable location on the top of the window.
This patchset introduces SaveRingMouseLocation() and changes
WarpToWindow() accordingly in order to create a unified mechanism
of mouse warping with always saving/restoring mouse location on
warp.
The 'ring.cursor_valid' variable is removed: the saved mouse
location is always valid, except if moving out of a client
crossing its window border, which is detected in
HandleLeaveNotify().
Second, if the client is resized, the saved location is set to its
initial default value (which is slightly to the right and up from
the middle of the client window) should it fall outside the window
during f.resize.
Last but most important, the semantics of f.warpto is extended to
allow an empty string as argument: f.warpto "".
This is a counterpart of f.warptoiconmgr "" as it warps mouse into
the client highlighted by the icon manager, or if none is
apparently highlighted, into the one having focus. This is one of
the insignificant changes to twm improving its
usability-by-keyboard dramatically.
A side note: f.warpring now honours the 'WarpUnmapped' .twmrc
parameter, the same way f.warpnext, f.warpprev do.
(22) diff22.twm-1.0.4.ActiveIconMgr
Many iconmanager related bugs are corrected not otherwise included
in previous patchsets.
Functions WarpToIconManager() and HideIconManager() are introduced
to enclose otherwise repeated code. (Now all iconmanagers can be
uniformly hidden/un-hidden.)
In ExecuteFunction() all iconmanager related F-functions are
enclused in "if (Scr->NoIconManagers == FALSE)" for clarity.
Now each screen may contain an 'active' iconmanager; the global
pointer 'Active' is gone. Each iconmanager can contain an
'active' entry (such as most recently used client in that
iconmanager).
MoveIconManager() and JumpIconManager() now try to activate an
iconmanager if none is active to perform the move/jump operation.
That activated iconmanager is considered as a result of move/jump.
This improves twm's usability-by-keyboard in that it should never
happen that twm doesn't respond to iconmanager navigation
functions (invoked by twm keybindings). Twm should always respond
in doing something meaningful, irrespective if iconmanagers are
mapped or not, or if there is some entry highlighted or not; and
the like (iconmanager navigation functions honour the
'WarpUnmapped' parameter whenever possible).
(Another story is if some client executes
XSetInputFocus (dpy, None, RevertToNone, CurrentTime);
and then exits. This may raise false impression of twm out of a
sudden not responding to keybindings because of twm bugs, which is
highly arguable in this situation. Mouse-button-bindings are
unaffected by this situation and moving mouse into some focusable
window restores the keybinding mechanism.)
(23) diff23.twm-1.0.4.TWM_USE_OPACITY
Twm supports the _XA_NET_WM_WINDOW_OPACITY property twofold. First
by .twmrc configuration this property can be set to twm own
graphical elements (menus, icons, iconmanagers, infowindow by
SetWindowOpacity(); and second, twm passes the client property to
its own-created frame window in HandleMapRequest() and
HandlePropertyNotify() by PropagateWindowOpacity(). It is up to
some background composite manager to do something with these
properties, twm doesn't care or expect anything.
(99) twm.man.diff99
Appends "REVISED EDITION; Eeri Kask, Dresden University of Technology"
to the man page to denote the above updates (improvements and bugs).
Eeri Kask Dresden, Sept 2007 ... Sept 2008
twm-1.0.4-tweaked-diffs.tar
(application/x-tar, 200 KB) - not displayed
TWM-RevisedEdition.png
(image/png, 131.4 KB) - not displayed