Saturday, August 25, 2007

clim-graphic-forms event handling still broken

Update 9/2/2007: in the time since I originally posted this entry, I figured out the problem. Every event dispatched to the McCLIM framework gets a timestamp, and these timestamps must be sane. Whereas before all currently queued events were getting their timestamps reset to the same value, I now make sure that each event is stamped using GFW:OBTAIN-EVENT-TIME. And so the annoying misbehaviors with decoration rendering, sizing, and moving of frames were resolved.

Original text follows:
---

Over the last several days, I made another attempt to fix event handling in clim-graphic-forms, which is a backend that I started for McCLIM using Graphic-Forms. The problem is hard to describe, but the most visible symptom is that top level windows act like non-client messages are only getting sporadically processed. For example, if I drag a top level window by its titlebar to a new location and let go, it becomes unresponsive to further mouse input until I deactivate and then reactivate the window. Or if I resize a window, the right and bottom frame decorations are not drawn -- even the titlebar doesn't resize. If I comment out the lines of code where I notify McCLIM via window configuration events, then of course McCLIM is prevented from doing what it needs to do, but the window frame starts to behave correctly.

The backend maintains an internal event queue which gets populated by various GFW:EVENT-*** methods and which is drained by CLIMI::GET-NEXT-EVENT. GET-NEXT-EVENT also has the job of retrieving each new message from Windows. I have experimented with several other approaches, including reimplementing CLIMI::SIMPLE-EVENT-LOOP to call GFW:MESSAGE-LOOP directly with a custom message filter that calls CLIMI::HANDLE-EVENT directly. The end result is the same.

I could work on filling in other missing functionality, but this event handling issue really bugs me to the point of extreme frustration. What is it about calling back into McCLIM during an event that causes such problems? I have no idea.

Monday, August 20, 2007

Graphic-Forms version 0.8.0

Release 0.8.0 of Graphic-Forms, a Common Lisp library for Windows GUI programming, is now available. The API and feature set is still evolving, so this is still another alpha release.

New in this release:

- Added a new macro GFW:DEFMENU2 and associated function GFW:MAKE-MENU to allow applications to create reusable menu factories.

- Latest CFFI is required to take advantage of built-in support for the stdcall calling convention as well as improved interface for defining foreign types and translators.

- Integrated patch submitted by Leon van Dyk that enables dialog-only applications. The GFT::STANDALONE-DIALOG function demonstrates this feature, but NOTE that when this is invoked from SLIME, an old problem reappears where the dialog is not initially visible; however, the same demo run directly from the REPL works OK.

- Ported the library to Allegro CL 8.0.

- Upgraded to LispWorks 5.0.1 (note: 4.4.6 is no longer supported)

- Implemented GFW:STATUS-BAR which currently allow a single text field. Multi-part status bars, and nested widget support, will be added in a future release.

- Implemented GFW:PROGRESS-BAR, which provides visual progress feedback. This control can be configured for horizontal or vertical orientation, and can display a segmented or continuous indicator.

- Simplified the mechanism for specifying fixed, non-resizable windows by adding a new GFW:TOP-LEVEL style called :FIXED-SIZE and enhancing GFW:PACK to do the right thing if that style flag has been specified.

- Greatly expanded the symbols for accessing predefined colors, and now provide access to system color settings in a similar manner.

- Implemented a new graphics context function GFG:CLEAR that is a convenient way to fill a window or image with a background color.

- GFS:OBTAIN-SYSTEM-METRICS now includes version information for comctl32.dll and shell32.dll.

The README.txt file in the release zip file also has additional important information about this release.

Download the release zip file here:
http://prdownloads.sourceforge.net/graphic-forms/graphic-forms-0.8.0.zip?download

The project website is:
http://common-lisp.net/project/graphic-forms/

Jack Unrue
jdunrue (at) gmail (dot) com
20 August 2007

Sunday, August 5, 2007

doc authoring system

When I work on a project, I generally try to write documentation in parallel with the code, even for projects that I don't intend to open source. Firstly, having that resource available frees up my mental bandwidth for thinking about the current problem I'm trying to solve. Secondly, it's a substitute (some might say a bad substitute) for certain kinds of design documentation, although I try hard to write docs with the end user in mind. And third, it's a way to sanity check ideas, such as when I'm designing some protocol. Having that stuff written down helps me see the big picture for what I'm trying to do, and providing it right away in the reference manual seems beneficial.

A while ago, I settled on DocBook/XSL as my authoring system. I use an extension of DocBook that I wrote which makes my personal style of structuring a CL project reference guide easier to build. It also provides some conveniences for the particular way that the syntax of CL functions/macros/etc are shown. The extensions are a set of XSL templates implementing some higher-level constructs that go along with the DocBook stylesheets; these get transformed into the DocBook vocabulary for later processing.

Here's an example of the help source for a function called MAKE-POINT in a package called LPC, using the extension vocabulary that I mentioned above:
<function name="make-point">
<syntax>
<arguments>
<argument name="coords">
<description>
One of:
<itemizedlist mark="bullet" spacing="compact">
<listitem>
A <refclhs>list</refclhs> of alternating x/y coordinate values.
</listitem>
<listitem>
An <refclhs>integer</refclhs> x coordinate value.
</listitem>
</itemizedlist>
</description>
</argument>
<notarg name="&optional"/>
<argument name="y-coord">
<description>
An <refclhs>integer</refclhs> y coordinate value.
</description>
</argument>
</arguments>
<return>
<refclhs>vector</refclhs>
</return>
</syntax>
<description>
This function returns a <refclhs>vector</refclhs> representing one or
more points.
</description>
<seealso>
<reftopic>lpc:point-x</reftopic>
<reftopic>lpc:point-y</reftopic>
<reftopic>lpc:point-elt</reftopic>
</seealso>
</function>
It's possible to mix tags from my extension vocabulary (e.g., function, syntax,
reftopic) with DocBook/XSL tags (e.g., itemizedlist, listitem).

This is what the end result looks like:

http://lispwidgets.net/make-point-doc.png

The output format is HTML Help, so the above screenshot shows part of the help viewer (it doesn't show the search/index tab nor the toolbar). My development platform is Windows XP. Not that there is anything wrong with portable solutions, and you know, raw HTML is often as good a choice as anything else. But HTML Help has features that I want, it's fairly customizable, and I can't think of many situations where a Windows user wouldn't have the viewer. Underlying this is the fact that I generally assume a Windows-based development environment for my work.

One future improvement I'd like to explore some day is to extract CL doc strings from the code and merge that in with other help content. I hear the SBCL developers do something along these lines to generate their manual, one difference being that I believe they are using texinfo or at least migrating in that direction, so I ought to take a look at what they do.