-------------------------------------------------------------------------
ABSTRACT
----------
With a few modifications to the Tk core, extensions could be written
that would allow X window managers to be implemented as Tcl/Tk scripts.
REQUIREMENTS
--------------
Writing X window managers in Tk requires some facilities that the
current Tk core doesn't provide. A window manager must be able to:
* draw to, and handle events on, the display's root window
(including _<Create>_, _<MapRequest>_, _<ResizeRequest>_,
_<CirculateRequest>_, and _<ConfigureRequest>_ events, which are
currently ignored)
* embed arbitrary windows inside Tk windows
* receive _<PropertyNotify>_ events from embedded windows
* perform a variety of other X-specific operations
Window embedding can be handled by an extension, if it is not
incorporated into the Tk frame widget at some later time. Likewise, the
X-specific operations can be handled by an extension. However, Tk as it
currently stands cannot access the display's root window, nor can
_<PropertyNotify>_ events be received from embedded windows; doing
these things requires core modifications.
ROOT WINDOW ACCESS
--------------------
The root window is special in many ways:
* It does not need to be created
* It cannot be destroyed, moved, or resized
* Only one process can receive _<ButtonPress>_ and
_<ButtonRelease>_ events from it, and only one process can have
the _SubstructureRedirect_ and _ResizeRedirect_ masks set
* It has no physical parent window
Because of these properties, access to the root window via a Tk widget
presents some difficulties. First, the widget's window cannot be
created in the standard way; however, this problem may be solved by
providing a non-standard creation routine via the _Tk_SetClassProcs_
procedure described in [TIP #5]. Likewise, the event handling required
by the root window can be enabled in an extension, although some care
is required when enabling _<ButtonPress>_ and certain other events.
What really causes problems is the lack of a physical parent. There are
many places in Tk where it is assumed that only toplevel widgets have
no physical parent within the application; this is reflected in the Tk
source by the use of the _TK_TOP_LEVEL_ flag. This flag is used to mean
different things in different places. In particular, the _TK_TOP_LEVEL_
flag may mean:
* This window is a toplevel widget
* This widget has a wrapper window
* This widget's window is controlled by the window manager
* This window is at the top of a physical window hierarchy within
the current application
In the current version of Tk, toplevel widgets have all of these
properties, and no other widgets have any of these properties; hence a
single flag suffices. If we create a widget whose window is the
display's root, then this is no longer the case; a root window has the
last property, but not the first three. For this reason, it is
necessary to replace the _TK_TOP_LEVEL_ flag with at least two distinct
flags. A better idea is to replace the _TK_TOP_LEVEL_ flag with four
flags, one for each of the properties listed above. (Even in a standard
Tk distribution, this replacement is desirable for documentation
reasons, since it will indicate what property of a toplevel widget is
important in the current circumstances.) We must also replace the
_Tk_IsTopLevel_ macro with several macros, or just eliminate it
entirely.
One possible set of flag names is:
TK_TOP_LEVEL:
this is a toplevel widget
TK_HAS_WRAPPER:
this window has a wrapper window
TK_WIN_MANAGED:
this window is controlled by the window manager
TK_TOP_HIERARCHY:
this window is at the top of a physical window hierarchy
NEW EVENT BINDINGS AND SUBSTITUTIONS
--------------------------------------
A window manager must be able to intercept certain events on the root
window that the standard Tk distribution doesn't recognize, and it must
be able to obtain information about those events. In particular, it
needs to respond to _<CirculateRequest>_, _<ConfigureRequest>_,
_<CreateNotify>_, _<MapRequest>_, and _<ResizeRequest>_ events. These
events are ignored by standard Tk, and need not be enabled by default;
however, they need to be included in the list of events recognized by
the Tk _[bind]_ command. Adding this facility is very simple.
Obtaining information about these events is also necessary. This is
usually done via %-substitutions in the _[bind]_ command; however,
there are two pieces of information that are necessary for implementing
a window manager that cannot be obtained via the current %-substitution
mechanism: the numerical X window ID, required to handle
_<CreateNotify>_ events, and the property name, for handling
_<PropertyNotify>_ events. This information could be obtained by adding
two new %-substitutions:
%i: substitute the numerical window ID for the event
%P: substitute the atom name for the property being changed
PROPAGATING <PROPERTYNOTIFY> EVENTS
-------------------------------------
In order to receive _<PropertyNotify>_ events from embedded windows,
the Tk event loop must handle events not just for windows that are
represented by _Tk_Window_ structures, but also for their children. One
way to accomplish this is to add another flag for the _Tk_Window_
struct, and alter the event loop so that it will also look at a
window's parent, if the event is a _<PropertyNotify>_ event. The
relevant part of the Tk event loop currently looks like this:
winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow);
if (winPtr == NULL) {
if (eventPtr->type == PropertyNotify) {
TkSelPropProc(eventPtr);
}
return;
}
If the flag for propagating _<PropertyNotify>_ events is
_TK_PROP_PROPCHANGE_, then the code above must be modified to look
approximately like this:
winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow);
if (winPtr == NULL) {
if (eventPtr->type != PropertyNotify) {
return;
}
TkSelPropProc(eventPtr);
parentXId = (parent of handlerWindow);
winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, parentXId);
if (winPtr == NULL) {
return;
}
if (!(winPtr->flags & TK_PROP_PROPCHANGE)) {
return;
}
handlerWindow = parentXId;
return;
}
PATCHES
---------
A patch (against tk8.4a2) that implements the changes described aboves
may be found at
<URL:http://www.eecs.umich.edu/~mckay/wmenablers.patch.gz>
COPYRIGHT
-----------
This document is in the public domain.
-------------------------------------------------------------------------
TIP AutoGenerator - written by Donal K. Fellows
[[Send Tcl/Tk announcements to tcl-an...@mitchell.org
Send administrivia to tcl-announ...@mitchell.org
Announcements archived at http://groups.yahoo.com/group/tcl_announce/
The primary Tcl/Tk archive is ftp://ftp.neosoft.com/pub/tcl/ ]]
Building my own X window manager with simple Tcl/Tk scripts, that's it
what would be make Tcl sexy! ;-)
No other scripting language has its own window manager.
Michael Barth
Morten
---------------------------
Evaluations of Linux Software
http://www.evalisoft.com
Reviews & Ratings of distros & programs
http://www.ensta.fr/internet/unix/window_managers/tkwm.html
,----
| Tkwm itself is just an extension to Tk that adds several commands that
| can be used to write a window manager. Packaged together with tkwm is
| stkwm, the "sample Tk window manager". This serves both as the de facto
| Tk based window manager, and as an example of how to write a window
| manager with tkwm. Users of MWM will find stkwm somewhat familiar, but
| stkwm is not intended to be an exact clone of any existing window
| manager. If you don't like the way it behaves feel free to change it,
| it's written in TCL after all.
`----
This is not a new idea. That thing above is from 1994.
Jochem
And I wrote a WM recently that uses Tcl and C that sends data via a pipe
to a Tk program which displays buttons for each window, and the GUI can
send map/raise/destroy messages through a socket to the Tcl C program
which handles the WM stuff. This way I didn't have to patch the core,
and it works well enough for what I was trying to do. The method
suggested in this TIP should be a lot more robust than what I've been
doing.
You can see the code I wrote for my WM here:
http://www.xmission.com/~georgeps/panache/
George
What: Tkwm
Where: <URL: http://www.dna.lth.se/%7Eerics/tkwm.html >
<URL: http://www.neosoft.com/tcl/ftparchive/sorted/x11/tkwm/0.1/ >
<URL: ftp://ftp.neosoft.com/languages/tcl/sorted/packages-7.6/devel/tkwm-0.9.1.tar.gz >
<URL: ftp://busco.lanl.gov/pub/tkwm-0.1a11.tar.gz >
Description: A Tcl/Tk window manager, based on extensions to Tk.
Updated: 02/2000
Contact: <URL: mailto:Majo...@comp.vuw.ac.nz > for mailing list subscriptions.
<URL: mailto:eric....@dna.lth.se > (Eric Schenk)
is the info I had most recently received about tkwm - if anyone has more
recent info please let me know. The software catalog at
<URL: http://www.purl.org/NET/Tcl-FAQ/part4.html> also had one
other effort which never apparently was announced as released - just mentioned
as 'contact the author for source'.
--
--
"See, he's not just anyone ... he's my son." Mark Schultz
<URL: mailto:lvi...@cas.org> <URL: http://www.purl.org/NET/lvirden/>
Even if explicitly stated to the contrary, nothing in this posting
A few years ago I wrote some core patches to allow me to write
window managers as Tcl/Tk scripts. (They were called the tkwm
patches, and are somewhere on the NeoSoft archives; if you try
to find them, just be aware that there's another project there called
tkwm, so you may have to hunt around under the X11 directory to
find the right stuff.) In the Tkwm patches, I had a (crude, but
usable) window manager written as a script. It's been a while, but
IIRC the script was about 1200 lines of code, much of which was
dedicated to creating window decorations.
--
Neil McKay
mc...@eecs.umich.edu