From: Scott L. <sl...@cs...> - 2002-04-22 07:28:59
|
Hi all. [Sorry this message isn't formatted for 80 columns] I've had about all the testing I can take at the moment, so I'm taking a short break to familarize myself with the C code and start thinking about plans and enhancements to make. I should get back to testing again shortly. Anyway, here are some random thoughts, ideas, comments, and questions for feedback. I just noticed the stuff about window properties that Maciej was adding. I'm not sure that this is a good approach. The way I see it, this basically replaces a lot of specific functions that do clear things with a general dispatching function that needs to have lots of magic constants/sysmbols/etc. defined for it to work. I don't really see much gain here. The main gain I see here is a logical place to attach new properties to windows. With an appropriate naming scheme, I think the individual functions capture most of the information here. Maybe what we need here is just to have the hooks for the specific events call a generic property change hook after they run. This seems to get most of the benefits (although I'm not even convinced this is necessary) without resorting to processing every kind of hook on every kind of event. I think the scwm-options stuff is more like the kind of interface we want. What we do need is some way to add information to the window thats needs to be used by some modules. Thoughts on this? I'm pretty fuzzy on what the problem even is that we are trying to solve here. I see a need for extensions to the information for each window, but I'm not sure this gets us anywhere. Anyway, that was actually just a side note. The main thing I've been thinking about is how to do the event/decoration rewrite correctly. I've grouped them together here since in my mind they are related and need to be thought about at the same time (because events can be bound to decoration elements). Probably need to implemented in the order event rewrite then decoration rewrite. I've looked over the stuff in doc/dev to gather up the ideas people had been thinking about. In general, I think the event proposal in doc/dev/events.gjb is pretty good, although I have a few comments and thoughts. First off, I think the idea of making events (make-key-event and friends) might a good idea IF we can wrap this for the user such that they can specify things more easily. It would be pretty irritating to have to make an event before you can bind a key in a keymap which then needs to be installed before it has any effect. I'm not sure this is a clear win though. Added this layer allows us to construct a little C structure to represent that type of event which could allow us to avoid reparsing the arguments if the event is reused. However, many events are global and thus only used once. It's also not clear this translation is expensive. I also think the repesentation of the event map is unlikely to use these structures since the event map should probably be represented as a hash. Then having these lying around in memory is just wasting space. Also, if we use these make-*-event routines, they should have a different name. As is, they sound like they are making an event that you could send to an app whereas they are being used to define slots to which event handlers can be bound. I like your ideas for event map objects in general. I agree that they should be attached to X windows (button, titles, frames, client windows, etc.). I'm not sure I agree with your commentary in make-event-map about relying on the geometry-based chaining of X11. Currently, we use the XShape extension to handle our squashed title bars. Fluxbox has a similar display element for their tabbed windows which looks similar on screen. However, instead of the shape extension they use a seperate window which has the root window as parent. This avoids the shape extension but means that they have to explicitly remember to move both windows whenever they move one. Which is better depends on the efficiency of the xshape extension and presumably on the area to which the shape extension is applied. I don't know enough to say whether this is a better way to do things, but relying on X to propagate the events precludes doing things this way. I'm not sure if X even gives the option of not propagating the event upwards though. I think allowing multiple parent event maps is confusing, error prone and doesn't buy us much. Hmm... just thought how that could be used to provide a nice keymap mixin ability though. I think we can get this same mixin type ability just through the normal parent mechanism if we seperate the concept of event maps and installed event maps (I think we might need this anyway to do the grabs properly). Then the installed event map could have the parent pointer and the event map itself has no parent. Oh, btw, the add-event-binding! primitive should be able to take a keymap as the way to process a key-binding so that we can get prefix key capability. There should be some mechanism for having the sub event map time out back to the normal key map for people who want it. Anyway, back to the parenting thing. A mixin would just correspond to inserting another keymap as the child of the current keymap. Not sure what the primitives would look like for all of this. Just spouting ideas to get feedback right now. For the event callbacks, I don't see why different kinds of events couldn't have different callback types. Makes things less orthogonal but saves the callbacks accessing some mysterious global variable. I don't understand the comment you made about the Common Lisp Object System method combination. I don't understand how CLOS is applicable, but maybe I'm just being dense. I also think we want to have some semantic classes to which event maps can be attached so you could say things like (attach-event-map 'maximize-button max-button-event-map). Semantic classes would also be useful for supporting the various wm hints. Some thoughts on decorations. I think we need to think general here. This means almost abritrary drawing primitives for drawing various effects (like pixmaps, gradients, colors, text, you name it) that should eventually live in modules that get dynamically loaded. This should allow for things like using a very simple style for small footprint machines (although, I don't think we are going to do to well on these anyway due to requiring guile) and using a native widget set like gtk to blend with the apps better. This could even allow gtk widgets on GNOME apps and qt widgets on KDE apps. I've been trying to keep two constraints in mind when thinking about this: 1) it should be possible to emulate any other window manager's look, 2) simple stuff should be simple to specify. These two are sort of at odds since 1 implies more features which implies more options while 2 implies fewer options to have to specify. I think this problem can be handled with utility routines to use common styles and reasonable defaults as appropriate. Another major issue is how to specify the layout to use. This is actually even more complex than it initially appears because of new features that are starting to appear in other window managers (assuming we stick to constraint 1). There are 3 features that I have seen that require special thought. The first is tabbed windows ala PWM, Fluxbox, and others. The basic idea is to group windows together into one frame and make a bunch of tab buttons to select which one to display. This looks cool and I'd like to support it. The second, which is even more tricky, is subdivided displays and frames. The basic idea here is to stick multiple windows in one frame and provide a bar inbetween them to control the relative size of the windows. This is usually a recursive binary partition but other grids are also possible. See the Ion window manager for a pretty example of this (http://www.students.tut.fi/~tuomov/ion/) [what is it with those wacky Fins, they come up with the most strange and interesting stuff, must be the winter]. I really want to support this as it leads to a very nice interface for driving the window manager mostly from the keyboard (the way I tend to do things). The third feature is a bit more exotic and not as useful but I'd like to support it if possible anyway. This feature is the workspace concept of amiwm (http://www.plig.org/xwinman/amiwm.html, see the second screen shot). The basic idea is several desktops that can be manipulating somewhat like windows. Sort of a nested window sort of thing. This is probably more difficult to support and since I don't think it is as useful, probably the right thing to do is not support at first in the rewrite but try to leave room for it. The common thread to these features is that they remove the 1:1 mapping between client windows and frames/decorations. I think the decoration rewrite should reflect this. Here's basically what I'm thinking at the moment. Main concepts: Container - an element in the window manager in which decorations can be arranged and client windows can be displayed (roughly equivalent to a frame [although may contain several client windows and the a client window can jump from container to container {although no 2 at the same time}]). There would be a n:m mapping from client windows to associated containers. Each client window would have a current container of NULL if not currently being displayed in any container. Containers can also hold other containers. Event maps can be attached to containers. Each window will have at least a small container always associated with it which corresponds to the parent frame currently used. [Not sure about this part: This can also have another frame to support decorations that jump with the window from container to container. For Fvwm style decorations, this would be the only container needed.] Layout - a layout specifies the layout of components within a container and enforces any constraints that need to be maintained. Basically, the layout is reponsible for figuring out the location and size of all the widgets in a container. Examples would be a grid layout, horizontal box, vertical box, etc. similar to tables, hboxs, vboxs, and the like in gtk. Layouts can be nested. Decoration - A primitive section of the screen to which an event map can be attached. Basically, these will be X windows. This will be the smallest thing to which an event map can be attached. Each decoration will have a list of drawing primitives to use to draw it. Decorations would have some sort of shaped flag. Drawing primitive - The basic primitives which can be used to draw stuff on the decorations. This would include things like relief button, text, pixmap, relief pattern, gradient, solid color, line, use gtk button, and so on. These need to be extensible by modules to allow for using widget libraries and such without making everyone suffer. Probably need an object to hold lists of these. Decorations, layout, and containers without client windows can share their specification across multiple instantiations. Probably sort of like the menu item/menu item in menu distinction. All of these settings should be changeable on the fly. There will be styling routines to help make specification for common styles. There will be styling routines for specifying things like fvwm style, wm2 style, etc. So here's how I see the different cases above being implemented. fvwm style - one container for each window, each button becomes a decoration, the border parts and corners become decorations, the title bar becomes a container holding the title, buttons. The button faces, title faces, and border faces become drawing primitive lists. Icons/menus are containers that don't have a client area. pwm style [tabbed windows] - one container for each group of windows. container is similar to fvwm stuff except has additional tab section. Tab buttons bound to switching the client window associated with the container's client area. Other bindings split/join groups of windows by creating/destroying containers dynamically. Note: this happens even when no client windows are being created. ion style [subdivided screen] - one container for entire screen. Container has several client areas within it along with decorations for the grab bars to resize the subparts. Windows get put into this container when captured and get a new client area created for them along with new decoration for the grab bar to resize them. Note: this means need to be able to add decorations to a container on the fly. Mixed ion/pwm/fvwm style can also be supported through similar means. Other interesting things you could do with this: make a mode that when you bump one window into another they become part of the same frame and move/iconify/etc together. This gets many of the same benefits as the constraint stuff. Implementation notes: The drawing primitives are mostly already there in the form of faces. Many more things need to be dynamic because less info is known up front. This means more dynamic data structures. Need to be careful in specification of all this to make easy things easy. This means common layout things need to be easy. Well, those are my thoughts so far. Let me know what you think, where there are holes, unimplementable stuff, overly general stuff, etc. I'm sure there are still major problems with this and it is still pretty wishy-washy right now but I thought some early feedback would be helpful. I see this as probably an immediately post-1.0 thing. This is going to shake up the interface a fair amount so this might require a rather major bump of version number. Which reminds me, we need to think about a convention for version numbers. Specifically, I think something in the version number needs to correspond to changes in the API. We need to figure out a correspondence between API changes and revision number bumps so people can tell what they are in for when upgrading (of course, we should try to keep backwards compatibility too). We also need a policy on backwards compatibility since it'll be too unwieldy to support everything forever. A lot of the current functions in the API have pretty arbitrary names. We should pick a naming scheme and try to stick to it and change all the old names to new names. There is the question of whether we should do this pre-1.0 or not. The argument against is things work as is and have been tested this way. The argument for is that the API should be somewhat stabilized with the 1.0 release and therefore this should happen before the 1.0 release. Well I better get some sleep now. Let me know what you'll think. - Scott |