]> git.mdlowis.com Git - proto/lwm.git/commitdiff
removed lots of stuff
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 9 Mar 2020 01:43:16 +0000 (21:43 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 9 Mar 2020 01:43:16 +0000 (21:43 -0400)
15 files changed:
.gitignore [new file with mode: 0644]
ChangeLog [deleted file]
Imakefile [deleted file]
build.sh [new file with mode: 0755]
client.c
cursor.c
disp.c
ewmh.c
lwm
lwm.c
lwm.h
lwm.man [deleted file]
manage.c
mouse.c [moved from shape.c with 73% similarity]
no_xmkmf_makefile [deleted file]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..4829287
--- /dev/null
@@ -0,0 +1,2 @@
+tags
+lwm
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644 (file)
index 0bc30a0..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,486 +0,0 @@
-Change Log for "lwm"
-
-2016-02-12     jfc     York
-       Patches from Greg Kenneky and other fixes for fullscreen windows.
-
-       Released lvm-1.2.4.
-
-2013-07-09     jfc     York
-       Applied a couple of minor patches suggested by Jari Aalto, the
-       Debian package maintainer.
-
-       Released lwm-1.2.3.
-
-
-2009-11-24     jfc     York
-       Released lwm-1.2.2.
-
-2009-11-20     jfc     York
-       Improved performance by only checking for pending X events when the
-       socket it ready for reading.
-
-       Fixed applyGravity() bug that caused frameless windows to be
-       mis-positioned.
-
-       Applied a workaround in destroy() to avoid error reports when closing
-       windows.
-
-2005-01-28     jfc     York
-
-       Applied a patch from Chris Reece that ensures that the popup
-       menu does not disappear off the bottom of the screen.
-
-2004-09-30     jfc     York
-
-       Fixed an issue with IRIX 6.5 and lwm, where the root menu could
-       not be used because motion events had coordinates with respect to
-       the popup, not the root. Fixed by explicitly using the root window
-       coordinates.
-
-       Released lwm-1.2.1.
-
-2004-09-28     jfc     York
-
-       Added missing -lSM to no_xmkmf_makefile.
-
-2003-12-09     jfc     York
-
-       Fixed bug (reported by Matthew Wilcox) where windows with extremely
-       long names could cause the pop menu to be unusable. Fixed by
-       maintaining a separate, shortened name for the menu, if
-       necessary ("this is a very very [...] ry long window name"). This
-       takes no account of UTF-8 names as yet.
-
-2003-12-08     jfc     York
-
-       Fixed bug (reported by Eugene Wong) where resizing the top of
-       a window would cause it to jump up several pixels. The height of
-       the titlebar was not being considered when calculating mouse
-       motion in reshaping_motionnotify().
-
-       Modified manage() to avoid autoplacing windows during
-       initialisation.
-
-       Released lwm-1.2.0.
-
-2003-12-03     jfc     York
-
-       Applied patch from Elliott that gives focus to new windows in
-       click-to-focus mode.
-
-       Changed the buttonpress code in disp.c to ignore scroll wheel
-       "clicks".
-
-       Modified Client_Remove so that, in click-to-focus mode, it
-       refocuses on the most sensible window (either the top window,
-       or the window that the closing window was a transient for).
-
-       Attempted to fix the edit placement bug by adding titleHeight()
-       to the supplied X coordinate during a ConfigureRequest event,
-       and not attempting to fix clients that don't supply a border
-       width during a configure request.
-
-       Fixed fullscreen-mode bug where galeon windows appeared to jump
-       up and to the left after the first click.
-
-       Released lwm-1.1.7.
-
-2003-11-28     jfc     York
-
-       Changed the behaviour when unhiding a window in click-to-focus mode.
-       An unhidden window now automatically gets focus in this mode.
-
-       Fixed a small bug in the session management code that could
-       cause a crash when lwm quit.
-
-       Moved a call to ewmh_set_client_list make before ewmh was
-       initialised.
-
-       Changed lwm's behaviour when minimising windows. Button three must
-       now be pressed and released before the window is hidden (or
-       moved to the bottom of the stack). This ensures that lwm swallows
-       all the events generated during the operation, and allows the user
-       to back out of the operation by moving the mouse out of the window
-       before releasing the button.
-
-       Removed include of Xm/MwmUtil.h in manage.c, and the HAVE_MOTIF
-       kludge from the Imakefile, in favour of copying the few lines
-       that are required from Xm/MwmUtil.h (LessTif, so hopefully no
-       licensing issues).
-
-       Fixed bug that caused the last cursor displayed in a frame
-       to be incorrectly used when moving into the frame when the
-       root menu was on screen. This is done by brute force -
-       see Client_ResetAllCursors().
-
-       Released lwm-1.1.6.
-
-2003-11-26     jfc     York
-
-       Fixed bug in Client_MakeSane that caused occasional crashes
-       during window moves/resizing. Should investigate why it occasionally
-       gets called with a NULL client.
-
-2003-11-03     jfc     York
-
-       Added an entry for LeaveNotify in the dispatch table (disp.c).
-
-2003-08-13     jfc     York
-
-       Removed "error" message when lwm fails to connect to a session
-       manager. This isn't actually an error and the message is confusing.
-
-2003-08-01     jfc     York
-
-       Fixed bug that allowed clients to grab the focus and confuse lwm.
-
-       Cleaned up the code for raising and lowering clients, and added
-       code to prevent a client from being raised above its transients.
-
-       Retired disp.old, and CLOSE_PATCH.txt.
-
-       Added an edge resistance to the workarea, so that window may
-       be moved to the edge of the workarea without precise mousing,
-       as requested by MAD. EDGE_RESIST in lwm.h defines the number of
-       pixels of resistance and may be safely set to zero.
-
-       Released lwm-1.1.5.
-
-2003-07-31     jfc     York
-
-       In click-to-focus mode, always draw the box in the frame.
-
-2003-07-29     jfc     York
-
-       Added a click-to-focus mode. The default remains (sloppy)
-       enter-to-focus.
-
-       Released lwm-1.1.4.
-
-
-2003-07-28     jfc     York
-
-       Updated no_xmkmf_makefile to reflect the changes made since 1.01.
-
-2003-07-10     jfc     York
-
-       Fixed a bug in manage.c than prevented lwm compiling on systems
-       with no variety of Motif installed. If this means you, remove
-       _DHAVE_MOTIF from Imakefile.
-
-       Released lwm-1.1.3.
-
-2003-07-08     jfc     York
-
-       Added support for NET_MOVERESIZE, but I cannot find any
-       applications the want to use it, apart from the keyboard
-       variants. I don't know what to do about the keyboard move/resize.
-
-2003-07-03     jfc     York
-
-       Fixed a few buglets thrown up by running lwm through the compiler
-       with all warnings on.
-
-2003-07-02     jfc     York
-
-       In Client_MakeSane(), added a check to prevent windows being
-       moved into a position where they might be completely obscured
-       by panels/docks.
-
-       Changed ewmh_set_strut() to run Client_MakeSane() across all
-       clients when the work area changes. This avoids clients getting
-       lost behind panels/docks.
-
-       Added support for _NET_WM_STATE_ABOVE and
-       _NET_WM_STATE_BELOW. Added fix_stack() to maintain the window
-       stack as dictated by the EWMH spec.
-
-2003-07-01     jfc     York
-
-       Added support for _NET_WM_STRUT. lwm now maintains _NET_WORKAREA
-       correctly, and takes the reserved space into account in its
-       window placing algorithm.
-
-       Released lwm-1.1.2.
-
-2003-06-30     jfc     York
-
-       Fixed bug that caused tk menus to be badly placed placed by
-       sending a configure notify where appropriate in setactive().
-
-       Removed compile time option of prepending window title's with
-       the client machines's name (PREPEND_CLIENT_MACHINE).
-
-       Added i18n support for window titles, using UTF8 names from
-       _NET_WM_NAME where available and supported (ie XFree86).
-
-       Added code in disp.c to change the pointer in some areas of the
-       frame to indicate the action taken by button1. I didn't allow the
-       "move" pointer in the titlebar because it looked nasty. Added
-       the xkill pointer for the the box. This was a TODO item.
-
-2003-06-28     jfc     York
-
-       Added GPL headers to all the source files.
-
-       Released lwm-1.1.1.
-
-2003-06-27     jfc     York
-
-       Fixed the bug where each GTK window generated an extra
-       window when lwm shut down by unmapping all the clients in
-       Client_FreeAll(). Elliott thinks this is bad magic, and that
-       the X server should lose the windows, but this doesn't happen
-       with XFree86.
-
-       Fixed bug, reported by Ed Porter, that caused moving the mouse
-       wheel to generate xterms. Wheel mice generate button press events
-       on buttons 4 and 5 and shell() wasn't taking this into account.
-
-       Fixed silly bug in motifWouldDecorate(): windows should have a
-       frame is MWM_DECOR_ALL is set.
-
-2003-06-26     jfc     York
-
-       Shaped windows now work again. I'm not sure what I changed
-       to break it, but the fix was to process shaped windows in
-       scanWindowTree (they were previously ignored). They had to be
-       clients anyway, if they were to appear in _NET_CLIENT_LIST.
-
-2003-06-25     jfc     York
-
-       Fixed bug that caused frameless windows to be immoveable.
-
-       In manage.c, allowed lwm to fall back on Motif hints when
-       deciding if a window should have a frame, if _NET_WM_WINDOW_TYPE
-       is not set. This breaks the EWMH spec, in that a window
-       without _NET_WM_WINDOW_TYPE should be assumed to have
-       _NET_WM_WINDOW_TYPE_NORMAL, but it's the only way for older
-       apps to indicate that they don't want decorating, and in the
-       absence of Motif hints the default state is
-       _NET_WM_WINDOW_TYPE_NORMAL.
-
-2003-06-24     jfc     York
-
-       Fixed the following TODO item:
-               allow users to back out of closing a window if
-               they leave the box before letting go of the button.
-       Implemented by adding an extra wm_closing_window mode rather
-       than adding to the Client structure, as per AMidthune's
-       patch. Not sure which is the better solution, though.
-
-       Added initial support for _NET_WM_STATE, but only for
-       _NET_WM_STATE_SKIP_TASKBAR, _NET_WM_STATE_SKIP_PAGER and
-       _NET_WM_HIDDEN.
-
-       Added simple hardwired _NET_WM_ALLOWED_ACTIONS support, and
-       support for the _NET_CLOSE_WINDOW client message.
-
-       First attempt an _WM_STATE_FULLSCREEN and a full-screen mode.
-       It's not quite right yet, but useable.
-
-
-2003-06-23     jfc     York
-
-       Fixed some silly bugs in the session management code.
-
-       Added initial EWMH code using the 1.2 spec:
-       http://www.freedesktop.org/standards/wm-spec/1.2/html/
-       Initial support covers the mechanisms for announcing support
-       for EWMH (_NET_SUPPORTED, _NET_SUPPORTING_WM_CHECK), the
-       client list and active client (_NET_CLIENT_LIST and
-       _NET_ACTIVE_WINDOW), and the window type (_NET_WM_WINDOW_TYPE).
-       Windows may now be frameless if their window type indicates.
-
-2003-06-21     jfc     York
-
-       Added session management so that GNOME2's gnome-session does
-       not wait a long timeout when starting the window manager.
-
-2000-02-08     enh     Basel
-       
-       Tried out a patch from Robert Bauer so that it's possible to move
-       windows with button 1, if you're in the ``titlebar'' (i.e. not touching
-       the top border). This makes it easier for Windows users to cope
-       with lwm, and easier for those with two-button mice (or laptops)
-       too. At the moment, "mv disp.old disp.c" will give back the old
-       behaviour.
-
-1999-11-11     enh     Basel
-
-       Fixed a cut-and-paste bug in client.c that made the check for
-       a window being too large or too small wrong. This bug was found
-       by Mike Meyer.
-
-1999-09-22     enh     Basel
-
-       Altered the button-press code so that it's now easier for unhappy
-       users to alter which button performs which function. Simply edit
-       lwm.h and modify the three relevant #define statements.
-
-1999-07-19     enh     Basel
-
-       Added a handler for circulation events so that other programs
-       can offer "Alt-Tab" functionality.
-
-1999-07-08     enh     Basel
-
-       Fixed the cosmetic problem with titlebars of dialogue boxes. If
-       this looks to be OK, I can think about another lwm release.
-
-1999-06-10     enh     Basel
-
-       Incorporated bug fix by Adrian Colley regarding the attempt in
-       manage.c to call XSetWindowBorderWidth on an InputOnly window,
-       and moved the #include of <signal.h> after <sys/types.h> so that
-       lwm can compile on Solaris 2.6. Cosmetic change to move the close
-       box to line up with the client window. The effect is spoilt if the
-       child insists on drawing a black border around itself, though.
-
-1999-02-07     enh     Basel
-       
-       Title-bars no longer pop up and down. An inactive window has a
-       grey title instead. This means less load on the server, no annoying
-       "I want to type the information from one window's title-bar into
-       the current window but can't" syndrome, and a final solution to
-       the race condition that's been with us since the very beginning.
-       
-       The size feedback no longer pops up as soon as you grab a window,
-       because that made it almost impossible to grab a window without
-       resizing it.
-
-1998-11-03     enh     Basel
-
-       The size feedback now pops up as soon as you grab a window,
-       rather than waiting for you to actually move.
-
-1998-10-06     enh     Basel
-
-       Al pointed out that my Sun actually has two framebuffers. One
-       monitor-lugging later, and I suddenly have a need for a window
-       manager that can cope with multiple screens. And here it is!
-
-1998-05-29     enh     Basel
-
-       Fixed window minimum/maximum height code so that it no longer
-       includes the title decoration. Menu now pops down if a window
-       disappears while the menu is up.
-
-1998-03-23     enh     Basel
-
-       Removed unused constant. A little tidying up, renaming.  Some
-       debugging code removed. The width of the size-feedback window
-       is now calculated at run-time depending on the size of the screen.
-
-1998-02-05     enh     Basel
-
-       Fixed bug found by Marty Olevitch: lwm's automatic window
-       placement heuristics broke down when either the right or bottom
-       of the display were reached.
-       Changed menu placement to ensure that the menu is fully
-       on-screen.
-
-1998-01-06     enh     Basel
-
-       Fixed bug found by J. Han whereby lwm dumped core if a window
-       disappeared while being reshaped.
-
-1997-09-01     enh     Basel
-
-       "Push to back" functionality moved from button 3 click in box
-       to button 3 click anywhere in frame with Shift held down.
-
-1997-08-29     enh     Basel
-
-       Simple version numbering introduced.
-
-1997-08-25     enh     Basel
-
-       Fixed stupid mistake introduced with the last change, with regard
-       to setting the input focus.
-
-1997-08-22     enh     Basel
-
-       Xt applications (strictly, applications whose window title is
-       the same as their class hint resource name) no longer have a
-       title bar. This means it's more awkward to kill them, but that
-       they don't have pointless decoration.
-
-1997-08-07     enh     Basel
-
-       Bug related to hiding windows fixed.
-
-1997-08-06     enh     Basel
-
-       The size indictor now has the correct GC settings. Whoops!
-       Improved handling of WM_NORMAL_HINTS. Amongst other things,
-       this means that size reporting of xterm et al is more reliable.
-
-1997-07-31     enh     Basel
-
-       Reshaping now uses the popup to display the current width and
-       height of the window being reshaped (in whatever units it uses).
-
-1997-07-04     enh     Swanwick
-
-       Clicking button 3 on the "box" pushes the window to the bottom.
-       Changing image in xv no longer causes the window to gravitate to
-       the southeast. There's an ICCCM convention that clients should
-       set the border width with each ConfigureWindow request. As usual,
-       many clients fail to follow this convention. I get the distinct
-       impression that the very reason for the existance of the Xt
-       library is because the X11 protocol and ICCCM are so messy and
-       involved that the only way to make X11 bearable was to write
-       this code once and for all. The menu code has been rewritten,
-       changing as a side-effect the order in which hidden windows
-       appear on the menu. The rewrite now means that the order is very
-       easy to change for experiments like alphabetical ordering etc. I
-       like it as it is: a stack.
-
-1997-06-24     enh     York
-
-       Now handles NoExpose events. Better protocol error reporting.
-       Default minimum size calculation improved.
-
-1997-06-23     enh     York
-
-       Both button 1 and 2 can now have commands associated with them.
-       See the documentation for details. Windows whose minimum and
-       maximum sizes are identical can no longer be resized. The
-       oscillation race condition is now less likely to occur. Some
-       dead code removed.
-
-1997-05-25     enh     York
-
-       lwm now does the right thing with respect to hidden windows on
-       exit and startup. a hidden window is now re-hidden if lwm exits
-       and is then restarted.
-
-1997-05-21     enh     York
-
-       Fixed a bug that meant a client could confuse lwm by remapping
-       a hidden window: the menu of hidden windows wasn't being updated.
-
-1997-05-16     enh     York
-
-       A bug relating to ConfigureRequests on the current window caused
-       the title-bar to be redrawn incorrectly. Once again, this came
-       to light with xv.
-
-       The "New Shell" command has gone from the button 3 menu, and
-       button 2 now performs this function.
-
-1997-05-09     enh     York
-
-       This version fixes a bug relating to ConfigureRequests. Client
-       windows that were resized under program control were resized,
-       but the client was misinformed as to what change had actually
-       taken place. xv's optimised redraw, for example, missed out on
-       part of the window because of this.
-       The behaviour with regard to hidden windows on exit has also
-       changed. They're now remapped, but lowered in the window stack.
-       This means that you don't lose them, but that they don't
-       obliterate the more important windows on your screen if you kill
-       the window manager.
-
-- Initial announcement on comp.windows.x.announce -
diff --git a/Imakefile b/Imakefile
deleted file mode 100644 (file)
index da76f1c..0000000
--- a/Imakefile
+++ /dev/null
@@ -1,29 +0,0 @@
-XCOMM lwm, a window manager for X11
-XCOMM Copyright (C) 1997-2016 Elliott Hughes, James Carter
-XCOMM 
-XCOMM This program is free software; you can redistribute it and/or
-XCOMM modify it under the terms of the GNU General Public License
-XCOMM as published by the Free Software Foundation; either version 2
-XCOMM of the License, or (at your option) any later version.
-XCOMM 
-XCOMM This program is distributed in the hope that it will be useful,
-XCOMM but WITHOUT ANY WARRANTY; without even the implied warranty of
-XCOMM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-XCOMM GNU General Public License for more details.
-XCOMM 
-XCOMM You should have received a copy of the GNU General Public License
-XCOMM along with this program; if not, write to the Free Software
-XCOMM Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-INCLUDES = -I$(TOP)
-DEPLIBS = $(DEPXLIB) $(DEPSMLIB)
-LOCAL_LIBRARIES = $(XLIB) $(SMLIB) -lICE
-DEFINES = -DSHAPE
-
-HEADERS = lwm.h ewmh.h
-SRCS = lwm.c manage.c mouse.c client.c cursor.c error.c disp.c shape.c resource.c session.c ewmh.c
-OBJS = ${SRCS:.c=.o}
-
-ComplexProgramTarget(lwm)
-
-${OBJS}: ${HEADERS}
diff --git a/build.sh b/build.sh
new file mode 100755 (executable)
index 0000000..623d39d
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+cc -g -o lwm *.c -I. -I/usr/X11/include/ -L/usr/X11/lib -lX11 -lICE -lSM
index e7bf09e4f9168ec90216cc77a88bd3f4135bf5a0..9189d38ba50f290af99253fa1f781d37a695ee0b 100644 (file)
--- a/client.c
+++ b/client.c
 Client *current;
 Client *last_focus = NULL;
 static Client *clients;
-
-static int popup_width;        /* The width of the size-feedback window. */
-
 Edge interacting_edge;
 
 static void sendClientMessage(Window, Atom, long, long);
 
 Client *
-client_head(void) {
-       return clients;
+Client_List(void) {
+    return clients;
 }
 
 void
-setactive(Client *c, int on, long timestamp) {
-       int inhibit;
-
-       if (c == 0 || hidden(c))
-               return;
-
-       inhibit = !c->framed;
-
-       if (!inhibit) {
-               XMoveResizeWindow(dpy, c->parent,
-                       c->size.x, c->size.y - titleHeight(),
-                       c->size.width, c->size.height + titleHeight());
-               XMoveWindow(dpy, c->window, border, border + titleHeight());
-               sendConfigureNotify(c);
-       }
-
-       if (on && c->accepts_focus) {
-               XSetInputFocus(dpy, c->window, RevertToPointerRoot, CurrentTime);
-               if (c->proto & Ptakefocus)
-                       sendClientMessage(c->window, wm_protocols,
-                               wm_take_focus, timestamp);
-               if (focus_mode == focus_click) {
-                       XUngrabButton(dpy, AnyButton, AnyModifier, c->window);
-               }
-               cmapfocus(c);
-       }
-
-       /* FIXME: is this sensible? */
-       if (on && !c->accepts_focus) {
-               XSetInputFocus(dpy, None, RevertToPointerRoot, CurrentTime);
-       }
-
-       if (!on && focus_mode == focus_click)
-               XGrabButton(dpy, AnyButton, AnyModifier, c->window, False,
-                       ButtonPressMask | ButtonReleaseMask, GrabModeAsync,
-                       GrabModeSync, None, None);
-
-       if (!inhibit)
-               Client_DrawBorder(c, on);
+Client_SetActive(Client *c, int on, long timestamp) {
+    int inhibit;
+
+    if (c == 0)
+        return;
+
+    inhibit = !c->framed;
+
+    if (!inhibit) {
+        XMoveResizeWindow(dpy, c->parent,
+            c->size.x, c->size.y - titleHeight(),
+            c->size.width, c->size.height + titleHeight());
+        XMoveWindow(dpy, c->window, border, border + titleHeight());
+        sendConfigureNotify(c);
+    }
+
+    if (on && Client_HasFlags(c, F_ACCEPT_FOCUS)) {
+        XSetInputFocus(dpy, c->window, RevertToPointerRoot, CurrentTime);
+        if (Client_HasFlags(c, F_EWMH_TAKE_FOCUS))
+            sendClientMessage(c->window, wm_protocols,
+                wm_take_focus, timestamp);
+    }
+
+    /* FIXME: is this sensible? */
+    if (on && !Client_HasFlags(c, F_ACCEPT_FOCUS)) {
+        XSetInputFocus(dpy, None, RevertToPointerRoot, CurrentTime);
+    }
+
+    if (!inhibit)
+        Client_DrawFrame(c, on);
 }
 
 
 void
-Client_DrawBorder(Client *c, int active) {
-       int quarter = (border + titleHeight()) / 4;
-
-       if (c->parent == c->screen->root || c->parent == 0 ||
-               c->framed == False || c->wstate.fullscreen == True)
-               return;
-
-       XSetWindowBackground(dpy, c->parent,
-               active ? c->screen->black : c->screen->gray);
-       XClearWindow(dpy, c->parent);
-
-       /* Draw the ``box''. */
-       if (active || focus_mode == focus_click) {
-               XDrawRectangle(dpy, c->parent, c->screen->gc,
-                       quarter + 2, quarter, 2 * quarter, 2 * quarter);
-       }
-
-       /* Draw window title. */
-       if (c->name != 0) {
-#ifdef X_HAVE_UTF8_STRING
-               if (c->name_utf8 == True)
-                       Xutf8DrawString(dpy, c->parent, font_set,
-                               c->screen->gc, border + 2 + (3 * quarter),
-                               2 + ascent(font_set_ext),
-                               c->name, c->namelen);
-               else
-#endif
-                       XmbDrawString(dpy, c->parent, font_set,
-                               c->screen->gc, border + 2 + (3 * quarter),
-                               2 + ascent(font_set_ext),
-                               c->name, c->namelen);
-       }
+Client_DrawFrame(Client *c, int active) {
+    int quarter = (border + titleHeight()) / 4;
+
+    if (c->parent == c->screen->root || c->parent == 0 || c->framed == False)
+        return;
+
+    XSetWindowBackground(dpy, c->parent,
+        active ? c->screen->black : c->screen->gray);
+    XClearWindow(dpy, c->parent);
+
+    /* Draw window title. */
+    if (c->name != 0) {
+        Xutf8DrawString(dpy, c->parent, font_set,
+            c->screen->gc, border + 2 + (3 * quarter),
+            2 + ascent(font_set_ext),
+            c->name, c->namelen);
+    }
 }
 
 
 Client *
 Client_Get(Window w) {
-       Client * c;
+    Client * c;
 
-       if (w == 0 || (getScreenFromRoot(w) != 0))
-               return 0;
+    if (w == 0 || (getScreenFromRoot(w) != 0))
+        return 0;
 
-       /* Search for the client corresponding to this window. */
-       for (c = clients; c; c = c->next)
-               if (c->window == w || c->parent == w)
-                       return c;
+    /* Search for the client corresponding to this window. */
+    for (c = clients; c; c = c->next)
+        if (c->window == w || c->parent == w)
+            return c;
 
-       /* Not found. */
-       return 0;
+    /* Not found. */
+    return 0;
 }
 
 
 Client *
 Client_Add(Window w, Window root) {
-       Client * c;
-
-       if (w == 0 || w == root)
-               return 0;
-
-       /* Search for the client corresponding to this window. */
-       for (c = clients; c != 0; c = c->next)
-               if (c->window == w || c->parent == w)
-                       return c;
-
-       c = calloc(1, sizeof *c);
-       c->window = w;
-       c->parent = root;
-       c->framed = False;
-       c->hidden = False;
-       c->state = WithdrawnState;
-       c->internal_state = INormal;
-       c->cmap = None;
-       c->name =  0;
-       c->menu_name =  0;
-       c->cursor = ENone;
-       c->wtype = WTypeNone;
-       c->wstate.skip_taskbar = False;
-       c->wstate.skip_pager = False;
-       c->wstate.fullscreen = False;
-       c->wstate.above = False;
-       c->wstate.below = False;
-       c->strut.left = 0;
-       c->strut.right = 0;
-       c->strut.top = 0;
-       c->strut.bottom = 0;
-       c->ncmapwins = 0;
-       c->cmapwins = 0;
-       c->wmcmaps = 0;
-       c->accepts_focus = 1;
-       c->next = clients;
-
-       /* Add to head of list of clients. */
-       clients = c;
-       return clients;
+    Client * c;
+
+    if (w == 0 || w == root)
+        return 0;
+
+    /* Search for the client corresponding to this window. */
+    for (c = clients; c != 0; c = c->next)
+        if (c->window == w || c->parent == w)
+            return c;
+
+    c = calloc(1, sizeof *c);
+    c->window = w;
+    c->parent = root;
+    c->framed = False;
+    c->state = WithdrawnState;
+    c->internal_state = INormal;
+    c->name =  0;
+    c->cursor = ENone;
+    c->wtype = WTypeNone;
+    c->flags |= F_ACCEPT_FOCUS;
+    c->next = clients;
+
+    /* Add to head of list of clients. */
+    clients = c;
+    return clients;
 }
 
 
 void
 Client_Remove(Client *c) {
-       Client * cc;
-       ScreenInfo *screen = c->screen;
-
-       if (c == 0)
-               return;
-
-       /* Remove the client from our client list. */
-       if (c == clients)
-               clients = c->next;
-       for (cc = clients; cc && cc->next; cc = cc->next) {
-               if (cc->next == c)
-                       cc->next = cc->next->next;
-       }
-
-       /* Remove it from the hidden list if it's hidden. */
-       if (hidden(c)) {
-               /* Al Smith points out that you also want to get rid of the menu
-                * so you can be sure that if you let go on an item, you always
-                * get the corresponding window. */
-               if (mode == wm_menu_up) {
-                       XUnmapWindow(dpy, current_screen->popup);
-                       mode = wm_idle;
-               }
-       }
-
-       /* A deleted window can no longer be the current window. */
-       if (c == current || (current == NULL && c == last_focus)) {
-               Client *focus = NULL;
-
-               /* As pointed out by J. Han, if a window disappears while it's
-                * being reshaped you need to get rid of the size indicator. */
-               if (c == current && mode == wm_reshaping) {
-                       XUnmapWindow(dpy, current_screen->popup);
-                       mode = wm_idle;
-               }
-               if (focus_mode == focus_click) {
-                       /* Try and find the window that this was a transient
-                        * for, else focus on the top client. */
-                       if (c->trans != None) {
-                               focus = Client_Get(c->trans);
-                       }
-                       if (!focus) {
-                               Window dw1;
-                               Window dw2;
-                               Window *wins;
-                               unsigned int nwins;
-
-                               XQueryTree(dpy, c->screen->root, &dw1,
-                                       &dw2, &wins, &nwins);
-                               while (nwins) {
-                                       focus = Client_Get(wins[nwins -1]);
-                                       if (focus) break;
-                                       nwins--;
-                               }
-                               if (wins) XFree(wins);
-                       }
-               }
-               Client_Focus(focus, CurrentTime);
-       }
-
-       if (getScreenFromRoot(c->parent) == 0)
-               XDestroyWindow(dpy, c->parent);
-
-       if (c->ncmapwins != 0) {
-               XFree(c->cmapwins);
-               free(c->wmcmaps);
-       }
-
-       if (c->name != 0)
-               free(c->name);
-       if (c->menu_name != 0)
-               free(c->name);
-
-       free(c);
-
-       ewmh_set_client_list(screen);
-       ewmh_set_strut(screen);
+    Client * cc;
+    ScreenInfo *screen = c->screen;
+
+    if (c == 0)
+        return;
+
+    /* Remove the client from our client list. */
+    if (c == clients)
+        clients = c->next;
+    for (cc = clients; cc && cc->next; cc = cc->next) {
+        if (cc->next == c)
+            cc->next = cc->next->next;
+    }
+
+    /* A deleted window can no longer be the current window. */
+    if (c == current || (current == NULL && c == last_focus)) {
+        Client *focus = NULL;
+        Client_Focus(focus, CurrentTime);
+    }
+
+    if (getScreenFromRoot(c->parent) == 0)
+        XDestroyWindow(dpy, c->parent);
+
+    if (c->name != 0)
+        free(c->name);
+    free(c);
+
+    ewmh_set_client_list(screen);
 }
 
 
 void
 Client_MakeSane(Client *c, Edge edge, int *x, int *y, int *dx, int *dy) {
-       Bool    horizontal_ok = True;
-       Bool    vertical_ok = True;
-
-       if (edge != ENone) {
-               /*
-                *      Make sure we're not making the window too small.
-                */
-               if (*dx < c->size.min_width)
-                       horizontal_ok = False;
-               if (*dy < c->size.min_height)
-                       vertical_ok = False;
-
-               /*
-                * Make sure we're not making the window too large.
-                */
-               if (c->size.flags & PMaxSize) {
-                       if (*dx > c->size.max_width)
-                               horizontal_ok = False;
-                       if (*dy > c->size.max_height)
-                               vertical_ok = False;
-               }
-
-               /*
-                * Make sure the window's width & height are multiples of
-                * the width & height increments (not including the base size).
-                */
-
-               if (c->size.width_inc > 1) {
-                       int apparent_dx = *dx - 2 * border - c->size.base_width;
-                       int x_fix = apparent_dx % c->size.width_inc;
-
-                       switch (edge) {
-                       case ELeft:
-                       case ETopLeft:
-                       case EBottomLeft:
-                               *x += x_fix;
-                               /*FALLTHROUGH*/
-                       case ERight:
-                       case ETopRight:
-                       case EBottomRight:
-                               *dx -= x_fix;
-                               break;
-                       default: break;
-                       }
-               }
-
-               if (c->size.height_inc > 1) {
-                       int apparent_dy = *dy - 2 * border - c->size.base_height;
-                       int y_fix = apparent_dy % c->size.height_inc;
-
-                       switch (edge) {
-                       case ETop:
-                       case ETopLeft:
-                       case ETopRight:
-                               *y += y_fix;
-                               /*FALLTHROUGH*/
-                       case EBottom:
-                       case EBottomLeft:
-                       case EBottomRight:
-                               *dy -= y_fix;
-                               break;
-                       default: break;
-                       }
-               }
-
-               /*
-                * Check that we may change the client horizontally and vertically.
-                */
-
-               if (c->size.width_inc == 0)
-                       horizontal_ok = False;
-               if (c->size.height_inc == 0)
-                       vertical_ok = False;
-       }
-
-       /* Ensure that at least one border is not entirely within the
-        * reserved areas. Keeping clients completely within the
-        * the workarea is too restrictive, but this measure means they
-        * should always be accessible.
-        * Of course all of this is only applicable if the client doesn't
-        * set a strut itself.                                  jfc
-        */
-       if (c->strut.left == 0 && c->strut.right == 0 &&
-               c->strut.top == 0 && c->strut.bottom == 0) {
-               if ((int)(*y + border) >=
-                       (int)(c->screen->display_height -
-                       c->screen->strut.bottom)) {
-                       *y = c->screen->display_height -
-                               c->screen->strut.bottom -border;
-               }
-               if ((int)(*y + c->size.height - border) <=
-                       (int)c->screen->strut.top) {
-                       *y = c->screen->strut.top + border - c->size.height;
-               }
-               if ((int)(*x + border) >=
-                       (int)(c->screen->display_width -
-                       c->screen->strut.right)) {
-                       *x = c->screen->display_width -
-                               c->screen->strut.right -border;
-               }
-               if ((int)(*x + c->size.width - border) <=
-                       (int)c->screen->strut.left) {
-                       *x = c->screen->strut.left + border - c->size.width;
-               }
-       }
-
-       /*
-        * Introduce a resistance to the workarea edge, so that windows may
-        * be "thrown" to the edge of the workarea without precise mousing,
-        * as requested by MAD.
-        */
-       if (*x < (int)c->screen->strut.left &&
-               *x > ((int)c->screen->strut.left - EDGE_RESIST)) {
-               *x =  (int)c->screen->strut.left;
-       }
-       if ((*x + c->size.width) >
-               (int)(c->screen->display_width - c->screen->strut.right) &&
-               (*x + c->size.width) <
-               (int)(c->screen->display_width - c->screen->strut.right +                       EDGE_RESIST)) {
-               *x = (int)(c->screen->display_width - c->screen->strut.right -
-                       c->size.width);
-       }
-       if ((*y - titleHeight()) < (int)c->screen->strut.top &&
-               (*y - titleHeight()) >
-               ((int)c->screen->strut.top - EDGE_RESIST)) {
-               *y =  (int)c->screen->strut.top + titleHeight();
-       }
-       if ((*y + c->size.height) >
-               (int)(c->screen->display_height - c->screen->strut.bottom) &&
-               (*y + c->size.height) <
-               (int)(c->screen->display_height - c->screen->strut.bottom +                     EDGE_RESIST)) {
-               *y = (int)(c->screen->display_height - c->screen->strut.bottom -
-                       c->size.height);
-       }
-
-       /*
-        * Update that part of the client information that we're happy with.
-        */
-       if (interacting_edge != ENone) {
-               if (horizontal_ok) {
-                       c->size.x = *x;
-                       c->size.width  = *dx;
-               }
-               if (vertical_ok) {
-                       c->size.y = *y;
-                       c->size.height = *dy;
-               }
-       } else {
-               if (horizontal_ok)
-                       c->size.x = *x;
-               if (vertical_ok)
-                       c->size.y = *y;
-       }
-}
-
-void
-size_expose(void) {
-       int width, height;
-       char buf[4*2 + 3 + 1];
-
-       width = current->size.width - 2*border;
-       height = current->size.height - 2*border;
-
-       /* This dance ensures that we report 80x24 for an xterm even when
-        * it has a scrollbar. */
-       if (current->size.flags & (PMinSize|PBaseSize) && current->size.flags & PResizeInc) {
-               if (current->size.flags & PBaseSize) {
-                       width -= current->size.base_width;
-                       height -= current->size.base_height;
-               } else {
-                       width -= current->size.min_width;
-                       height -= current->size.min_height;
-               }
-       }
-
-       if (current->size.width_inc != 0)
-               width /= current->size.width_inc;
-       if (current->size.height_inc != 0)
-               height /= current->size.height_inc;
-
-       snprintf(buf, sizeof(buf), "%i x %i", width, height);
-       XmbDrawString(dpy, current_screen->popup, popup_font_set,
-               current_screen->size_gc,
-               (popup_width - popupWidth(buf, strlen(buf))) / 2,
-               ascent(popup_font_set_ext) + 1, buf, strlen(buf));
+    Bool    horizontal_ok = True;
+    Bool    vertical_ok = True;
+
+    if (edge != ENone) {
+        /*
+         *  Make sure we're not making the window too small.
+         */
+        if (*dx < c->size.min_width)
+            horizontal_ok = False;
+        if (*dy < c->size.min_height)
+            vertical_ok = False;
+
+        /*
+         * Make sure we're not making the window too large.
+         */
+        if (c->size.flags & PMaxSize) {
+            if (*dx > c->size.max_width)
+                horizontal_ok = False;
+            if (*dy > c->size.max_height)
+                vertical_ok = False;
+        }
+
+        /*
+         * Make sure the window's width & height are multiples of
+         * the width & height increments (not including the base size).
+         */
+
+        if (c->size.width_inc > 1) {
+            int apparent_dx = *dx - 2 * border - c->size.base_width;
+            int x_fix = apparent_dx % c->size.width_inc;
+
+            switch (edge) {
+            case ELeft:
+            case ETopLeft:
+            case EBottomLeft:
+                *x += x_fix;
+                /*FALLTHROUGH*/
+            case ERight:
+            case ETopRight:
+            case EBottomRight:
+                *dx -= x_fix;
+                break;
+            default: break;
+            }
+        }
+
+        if (c->size.height_inc > 1) {
+            int apparent_dy = *dy - 2 * border - c->size.base_height;
+            int y_fix = apparent_dy % c->size.height_inc;
+
+            switch (edge) {
+            case ETop:
+            case ETopLeft:
+            case ETopRight:
+                *y += y_fix;
+                /*FALLTHROUGH*/
+            case EBottom:
+            case EBottomLeft:
+            case EBottomRight:
+                *dy -= y_fix;
+                break;
+            default: break;
+            }
+        }
+
+        /*
+         * Check that we may change the client horizontally and vertically.
+         */
+
+        if (c->size.width_inc == 0)
+            horizontal_ok = False;
+        if (c->size.height_inc == 0)
+            vertical_ok = False;
+    }
+
+    /*
+     * Update that part of the client information that we're happy with.
+     */
+    if (interacting_edge != ENone) {
+        if (horizontal_ok) {
+            c->size.x = *x;
+            c->size.width  = *dx;
+        }
+        if (vertical_ok) {
+            c->size.y = *y;
+            c->size.height = *dy;
+        }
+    } else {
+        if (horizontal_ok)
+            c->size.x = *x;
+        if (vertical_ok)
+            c->size.y = *y;
+    }
 }
 
 static void
 Client_OpaquePrimitive(Client *c, Edge edge) {
-       Cursor cursor;
-       int ox, oy;
-
-       if (c == 0 /*|| c != current*/)
-               return;
-
-       /* Find out where we've got hold of the window. */
-       getMousePosition(&ox, &oy);
-       ox = c->size.x - ox;
-       oy = c->size.y - oy;
-
-       cursor = getEdgeCursor(edge);
-       XChangeActivePointerGrab(dpy, ButtonMask | PointerMotionHintMask |
-               ButtonMotionMask | OwnerGrabButtonMask, cursor, CurrentTime);
-
-       /*
-        * Store some state so that we can get back into the main event
-        * dispatching thing.
-        */
-       interacting_edge = edge;
-       start_x = ox;
-       start_y = oy;
-       mode = wm_reshaping;
-       ewmh_set_client_list(c->screen);
+    Cursor cursor;
+    int ox, oy;
+
+    if (c == 0 /*|| c != current*/)
+        return;
+
+    /* Find out where we've got hold of the window. */
+    getMousePosition(&ox, &oy);
+    ox = c->size.x - ox;
+    oy = c->size.y - oy;
+
+    cursor = getEdgeCursor(edge);
+    XChangeActivePointerGrab(dpy, ButtonMask | PointerMotionHintMask |
+        ButtonMotionMask | OwnerGrabButtonMask, cursor, CurrentTime);
+
+    /*
+     * Store some state so that we can get back into the main event
+     * dispatching thing.
+     */
+    interacting_edge = edge;
+    start_x = ox;
+    start_y = oy;
+    mode = wm_reshaping;
+    ewmh_set_client_list(c->screen);
 }
 
 void
 Client_Lower(Client *c)
 {
-       if (c == 0) return;
+    if (c == 0) return;
 
-       XLowerWindow(dpy, c->window);
-       if (c->framed) XLowerWindow(dpy, c->parent);
-       ewmh_set_client_list(c->screen);
+    XLowerWindow(dpy, c->window);
+    if (c->framed) XLowerWindow(dpy, c->parent);
+    ewmh_set_client_list(c->screen);
 }
 
 void
 Client_Raise(Client *c)
 {
-       Client * trans;
+    Client * trans;
 
-       if (c == 0) return;
+    if (c == 0) return;
 
-       if (c->framed) XRaiseWindow(dpy, c->parent);
-       XRaiseWindow(dpy, c->window);
+    if (c->framed) XRaiseWindow(dpy, c->parent);
+    XRaiseWindow(dpy, c->window);
 
-       for (trans = clients; trans != NULL; trans = trans->next) {
-               if (trans->trans != c->window &&
-                       !(c->framed == True && trans->trans == c->parent))
-                       continue;
-               if (trans->framed) XRaiseWindow(dpy, trans->parent);
-               XRaiseWindow(dpy, trans->window);
-       }
+    for (trans = clients; trans != NULL; trans = trans->next) {
+        if (trans->trans != c->window &&
+            !(c->framed == True && trans->trans == c->parent))
+            continue;
+        if (trans->framed) XRaiseWindow(dpy, trans->parent);
+        XRaiseWindow(dpy, trans->window);
+    }
 
-       ewmh_set_client_list(c->screen);
+    ewmh_set_client_list(c->screen);
 }
 
 void
 Client_Close(Client *c) {
-       if (c == 0)
-               return;
-
-       /*
-        *      Terminate the client nicely if possible. Be brutal otherwise.
-        */
-       if (c->proto & Pdelete) {
-               sendClientMessage(c->window, wm_protocols, wm_delete, CurrentTime);
-       } else {
-               XKillClient(dpy, c->window);
-       }
+    if (c == 0) return;
+    if (Client_HasFlags(c, F_EWMH_DELETE)) {
+        sendClientMessage(c->window, wm_protocols, wm_delete, CurrentTime);
+    } else {
+        XKillClient(dpy, c->window);
+    }
 }
 
 void
 Client_SetState(Client *c, int state) {
-       long    data[2];
+    long    data[2];
 
-       data[0] = (long) state;
-       data[1] = (long) None;
+    data[0] = (long) state;
+    data[1] = (long) None;
 
-       c->state = state;
-       XChangeProperty(dpy, c->window, wm_state, wm_state, 32,
-               PropModeReplace, (unsigned char *) data, 2);
-       ewmh_set_state(c);
-}
-
-static void
-sendClientMessage(Window w, Atom a, long data0, long data1) {
-       XEvent  ev;
-       long    mask;
-
-       memset(&ev, 0, sizeof(ev));
-       ev.xclient.type = ClientMessage;
-       ev.xclient.window = w;
-       ev.xclient.message_type = a;
-       ev.xclient.format = 32;
-       ev.xclient.data.l[0] = data0;
-       ev.xclient.data.l[1] = data1;
-       mask = (getScreenFromRoot(w) != 0) ? SubstructureRedirectMask : 0L;
-
-       XSendEvent(dpy, w, False, mask, &ev);
+    c->state = state;
 }
 
 extern void
 Client_ResetAllCursors(void) {
-       Client *c;
-       XSetWindowAttributes attr;
-
-       for (c = clients; c; c = c->next) {
-               if (c->framed != True) continue;
-               attr.cursor = c->screen->root_cursor;
-               XChangeWindowAttributes(dpy, c->parent,
-                       CWCursor, &attr);
-               c->cursor = ENone;
-       }
-}
-
-extern void
-Client_FreeAll(void) {
-       Client *c;
-       XWindowChanges wc;
-
-       for (c = clients; c; c = c->next) {
-               int not_mapped = !normal(c);
-
-               /* elliott thinks leaving window unmapped causes the x server
-                * to lose them when the window manager quits. it doesn't
-                * happen to me with XFree86's Xnest, but unmapping the
-                * windows stops gtk window generating an extra window when
-                * the window manager quits.
-                * who is right? only time will tell....
-                */
-               XUnmapWindow(dpy, c->parent);
-               XUnmapWindow(dpy, c->window);
-               /* Remap the window if it's hidden.
-               if (not_mapped) {
-                       XMapWindow(dpy, c->parent);
-                       XMapWindow(dpy, c->window);
-               } */
-
-               /* Reparent it, and then push it to the bottom if it was hidden. */
-               XReparentWindow(dpy, c->window, c->screen->root, c->size.x, c->size.y);
-               if (not_mapped)
-                       XLowerWindow(dpy, c->window);
-
-               /* Give it back its initial border width. */
-               wc.border_width = c->border;
-               XConfigureWindow(dpy, c->window, CWBorderWidth, &wc);
-       }
-}
-
-extern void
-Client_ColourMap(XEvent *e) {
-       int i;
-       Client * c;
-
-       for (c = clients; c; c = c->next) {
-               for (i = 0; i < c->ncmapwins; i++) {
-                       if (c->cmapwins[i] == e->xcolormap.window) {
-                               c->wmcmaps[i] = e->xcolormap.colormap;
-                               if (c == current)
-                                       cmapfocus(c);
-                               return;
-                       }
-               }
-       }
+    Client *c;
+    XSetWindowAttributes attr;
+
+    for (c = clients; c; c = c->next) {
+        if (c->framed != True) continue;
+        attr.cursor = c->screen->root_cursor;
+        XChangeWindowAttributes(dpy, c->parent,
+            CWCursor, &attr);
+        c->cursor = ENone;
+    }
 }
 
 extern void
 Client_ReshapeEdge(Client *c, Edge e) {
-       Client_OpaquePrimitive(c, e);
+    Client_OpaquePrimitive(c, e);
 }
 
 extern void
 Client_Move(Client *c) {
-       Client_OpaquePrimitive(c, ENone);
+    Client_OpaquePrimitive(c, ENone);
 }
 
 extern int
-hidden(Client *c) {
-       return c->state == IconicState;
-}
-
-extern int
-withdrawn(Client *c) {
-       return c->state == WithdrawnState;
-}
-
-extern int
-normal(Client *c) {
-       return c->state == NormalState;
+Client_IsState(Client *c, int state)
+{
+    return c->state == state;
 }
 
 extern void
-Client_EnterFullScreen(Client *c) {
-       XWindowChanges fs;
-
-       memcpy(&c->return_size, &c->size, sizeof(XSizeHints));
-       if (c->framed) {
-               c->size.x = fs.x = -border;
-               c->size.y = fs.y = -border;
-               c->size.width = fs.width =
-                       c->screen->display_width + 2 * border;
-               c->size.height = fs.height =
-                       c->screen->display_height + 2 * border;
-               XConfigureWindow(dpy, c->parent,
-                       CWX | CWY | CWWidth | CWHeight, &fs);
-
-               fs.x = border;
-               fs.y = border;
-               fs.width = c->screen->display_width;
-               fs.height = c->screen->display_height;
-               XConfigureWindow(dpy, c->window,
-                       CWX | CWY | CWWidth | CWHeight, &fs);
-               XRaiseWindow(dpy,c->parent);
-       } else {
-               c->size.x = c->size.y = fs.x = fs.y = 0;
-               c->size.width = fs.width = c->screen->display_width;
-               c->size.height = fs.height = c->screen->display_height;
-               XConfigureWindow(dpy, c->window,
-                       CWX | CWY | CWWidth | CWHeight, &fs);
-               XRaiseWindow(dpy,c->window);
-       }
-       sendConfigureNotify(c);
+Client_Focus(Client *c, Time time) {
+    if (current) {
+        Client_SetActive(current, 0, 0L);
+        XDeleteProperty(dpy, current->screen->root,
+            ewmh_atom[_NET_ACTIVE_WINDOW]);
+    }
+
+    if (!c && current) {
+        last_focus = current;
+    } else {
+        last_focus = NULL;
+    }
+    current = c;
+    if (c) {
+        Client_SetActive(current, 1, time);
+        XChangeProperty(dpy, current->screen->root,
+            ewmh_atom[_NET_ACTIVE_WINDOW],
+            XA_WINDOW, 32, PropModeReplace,
+            (unsigned char *)&current->window, 1);
+    }
 }
 
 extern void
-Client_ExitFullScreen(Client *c) {
-       XWindowChanges fs;
-
-       memcpy(&c->size, &c->return_size, sizeof(XSizeHints));
-       if (c->framed == True) {
-               fs.x = c->size.x;
-               fs.y = c->size.y - titleHeight();
-               fs.width = c->size.width;
-               fs.height = c->size.height + titleHeight();
-               XConfigureWindow(dpy, c->parent,
-                       CWX | CWY | CWWidth | CWHeight, &fs);
-
-               fs.x = border;
-               fs.y = border + titleHeight();
-               fs.width = c->size.width -(2 * border);
-               fs.height = c->size.height -(2 * border);
-               XConfigureWindow(dpy, c->window,
-                       CWX | CWY | CWWidth | CWHeight, &fs);
-       } else {
-               fs.x = c->size.x;
-               fs.y = c->size.y;
-               fs.width = c->size.width;
-               fs.height = c->size.height;
-               XConfigureWindow(dpy, c->window,
-                       CWX | CWY | CWWidth | CWHeight, &fs);
-       }
-       sendConfigureNotify(c);
+Client_Name(Client *c, const char *name) {
+    if (c->name) free(c->name);
+    c->name = strdup((char *) name);
+    c->namelen = strlen(c->name);
 }
 
-extern void
-Client_Focus(Client *c, Time time) {
-       if (current) {
-               setactive(current, 0, 0L);
-               XDeleteProperty(dpy, current->screen->root,
-                       ewmh_atom[_NET_ACTIVE_WINDOW]);
-       }
-
-       if (!c && current) {
-               last_focus = current;
-       } else {
-               last_focus = NULL;
-       }
-       current = c;
-       if (c) {
-               setactive(current, 1, time);
-               XChangeProperty(dpy, current->screen->root,
-                       ewmh_atom[_NET_ACTIVE_WINDOW],
-                       XA_WINDOW, 32, PropModeReplace,
-                       (unsigned char *)&current->window, 1);
-       }
-
-       if (focus_mode == focus_click)
-               Client_Raise(c);
+int Client_HasFlags(Client* c, int flags) {
+    return ((c->flags & flags) == flags);
 }
 
-extern void
-Client_Name(Client *c, const char *name, Bool is_utf8) {
-       int tx;
-       static const char dots[] = " [...] ";
-       int cut;
-
-       if (c->name) free(c->name);
-       c->name = strdup((char *) name);
-       c->namelen = strlen(c->name);
-       c->name_utf8 = is_utf8;
-
-       if (c->menu_name) free(c->menu_name);
-       c->menu_name = 0;
-       tx = titleWidth(popup_font_set, c);
-       if (tx <= (c->screen->display_width - (c->screen->display_width / 10)))
-               return;
-
-       /* the menu entry for this client will not fit on the display
-        * (minus 10% for saftey), so produced a truncated version...
-        */
-       cut = 5;
-       do {
-               if (c->menu_name) {
-                       free(c->menu_name);
-                       c->menu_name = 0;
-               }
-               if (cut >= (strlen(c->name) / 2)) break;
-               c->menu_name = strdup(c->name);
-               /* FIXME: this is not UTF-8 safe! */
-               sprintf(&c->menu_name[(strlen(c->name) / 2) - cut], dots);
-               strcat(c->menu_name,
-                       &c->name[(strlen(c->name) / 2) + cut]);
-               c->menu_namelen = strlen(c->menu_name);
-               cut++;
-               tx = titleWidth(popup_font_set, c);
-               if (!tx) break;
-       } while (tx >
-               (c->screen->display_width - (c->screen->display_width / 10)));
+static void
+sendClientMessage(Window w, Atom a, long data0, long data1) {
+    XEvent  ev;
+    long    mask;
+
+    memset(&ev, 0, sizeof(ev));
+    ev.xclient.type = ClientMessage;
+    ev.xclient.window = w;
+    ev.xclient.message_type = a;
+    ev.xclient.format = 32;
+    ev.xclient.data.l[0] = data0;
+    ev.xclient.data.l[1] = data1;
+    mask = (getScreenFromRoot(w) != 0) ? SubstructureRedirectMask : 0L;
+
+    XSendEvent(dpy, w, False, mask, &ev);
 }
+
index f528095ec40a50d17dd76301e3c0b71aeaba6010..a689f956b690352f3a1a9a964e616ab20c83ddb8 100644 (file)
--- a/cursor.c
+++ b/cursor.c
 
 typedef struct CursorMapping CursorMapping;
 struct CursorMapping {
-       Edge edge;
-       int font_char;
+    Edge edge;
+    int font_char;
 };
 
 static CursorMapping cursor_map[] = {
-       {ETopLeft,     XC_top_left_corner},
-       {ETop,         XC_top_side},
-       {ETopRight,    XC_top_right_corner},
-       {ERight,       XC_right_side},
-       {ENone,        XC_fleur},
-       {ELeft,        XC_left_side},
-       {EBottomLeft,  XC_bottom_left_corner},
-       {EBottom,      XC_bottom_side},
-       {EBottomRight, XC_bottom_right_corner},
-       {ENone,        0},
+    {ETopLeft,      XC_top_left_corner},
+    {ETop,      XC_top_side},
+    {ETopRight, XC_top_right_corner},
+    {ERight,        XC_right_side},
+    {ENone,     XC_fleur},
+    {ELeft,     XC_left_side},
+    {EBottomLeft,   XC_bottom_left_corner},
+    {EBottom,       XC_bottom_side},
+    {EBottomRight,  XC_bottom_right_corner},
+    {ENone,     0},
 };
 
 extern void
 initialiseCursors(int screen) {
-       XColor red, white, exact;
-       Colormap cmp;
-       int i;
+    XColor red, white, exact;
+    Colormap cmp;
+    int i;
 
-       cmp = DefaultColormap(dpy, screen);
+    cmp = DefaultColormap(dpy, screen);
 
-       XAllocNamedColor(dpy, cmp, "red", &red, &exact);
-       XAllocNamedColor(dpy, cmp, "white", &white, &exact);
+    XAllocNamedColor(dpy, cmp, "red", &red, &exact);
+    XAllocNamedColor(dpy, cmp, "white", &white, &exact);
 
-       screens[screen].root_cursor = XCreateFontCursor(dpy, XC_left_ptr);
-       XRecolorCursor(dpy, screens[screen].root_cursor, &red, &white);
+    screens[screen].root_cursor = XCreateFontCursor(dpy, XC_left_ptr);
+    XRecolorCursor(dpy, screens[screen].root_cursor, &red, &white);
 
-       screens[screen].box_cursor = XCreateFontCursor(dpy, XC_draped_box);
-       XRecolorCursor(dpy, screens[screen].box_cursor, &red, &white);
+    screens[screen].box_cursor = XCreateFontCursor(dpy, XC_draped_box);
+    XRecolorCursor(dpy, screens[screen].box_cursor, &red, &white);
 
-       for (i = 0; cursor_map[i].font_char != 0; i++) {
-               Edge e = cursor_map[i].edge;
-               screens[screen].cursor_map[e] =
-                       XCreateFontCursor(dpy, cursor_map[i].font_char);
-               XRecolorCursor(dpy, screens[screen].cursor_map[e],
-                       &red, &white);
-       }
+    for (i = 0; cursor_map[i].font_char != 0; i++) {
+        Edge e = cursor_map[i].edge;
+        screens[screen].cursor_map[e] =
+            XCreateFontCursor(dpy, cursor_map[i].font_char);
+        XRecolorCursor(dpy, screens[screen].cursor_map[e],
+            &red, &white);
+    }
 }
 
 extern Cursor
 getEdgeCursor(Edge edge) {
-       return screens[0].cursor_map[edge];
+    return screens[0].cursor_map[edge];
 }
diff --git a/disp.c b/disp.c
index bdf1d9d7f72477d9bfe81646fa1ceeba8b5fd585..44c9189e75cc6b2f29f2f4d86d5fe0385533f266 100644 (file)
--- a/disp.c
+++ b/disp.c
 #include "ewmh.h"
 
 /*
- *     Dispatcher for main event loop.
+ *  Dispatcher for main event loop.
  */
 typedef struct Disp Disp;
 struct Disp {
-       int     type;
-       void    (*handler)(XEvent *);
+    int type;
+    void    (*handler)(XEvent *);
 };
 
 static void expose(XEvent *);
 static void buttonpress(XEvent *);
-static void buttonrelease(XEvent *);
+static void buttonrelease(XEvent *ev);
 static void focuschange(XEvent *);
 static void maprequest(XEvent *);
 static void configurereq(XEvent *);
 static void unmap(XEvent *);
 static void destroy(XEvent *);
 static void clientmessage(XEvent *);
-static void colormap(XEvent *);
 static void property(XEvent *);
 static void reparent(XEvent *);
 static void enter(XEvent *);
 static void circulaterequest(XEvent *);
 static void motionnotify(XEvent *);
-
-void reshaping_motionnotify(XEvent *);
+static void reshaping_motionnotify(XEvent *);
 
 static Disp disps[] =
 {
-       {Expose, expose},
-       {MotionNotify, motionnotify},
-       {ButtonPress, buttonpress},
-       {ButtonRelease, buttonrelease},
-       {FocusIn, focuschange},
-       {FocusOut, focuschange},
-       {MapRequest, maprequest},
-       {ConfigureRequest, configurereq},
-       {UnmapNotify, unmap},
-       {DestroyNotify, destroy},
-       {ClientMessage, clientmessage},
-       {ColormapNotify, colormap},
-       {PropertyNotify, property},
-       {ReparentNotify, reparent},
-       {EnterNotify, enter},
-       {CirculateRequest, circulaterequest},
-       {LeaveNotify, 0},
-       {ConfigureNotify, 0},
-       {CreateNotify, 0},
-       {GravityNotify, 0},
-       {MapNotify, 0},
-       {MappingNotify, 0},
-       {SelectionClear, 0},
-       {SelectionNotify, 0},
-       {SelectionRequest, 0},
-       {NoExpose, 0},
+    {Expose, expose},
+    {MotionNotify, motionnotify},
+    {ButtonPress, buttonpress},
+    {ButtonRelease, buttonrelease},
+    {FocusIn, focuschange},
+    {FocusOut, focuschange},
+    {MapRequest, maprequest},
+    {ConfigureRequest, configurereq},
+    {UnmapNotify, unmap},
+    {DestroyNotify, destroy},
+    {ClientMessage, clientmessage},
+    {PropertyNotify, property},
+    {ReparentNotify, reparent},
+    {EnterNotify, enter},
+    {CirculateRequest, circulaterequest},
+    {LeaveNotify, 0},
+    {ConfigureNotify, 0},
+    {CreateNotify, 0},
+    {GravityNotify, 0},
+    {MapNotify, 0},
+    {MappingNotify, 0},
+    {SelectionClear, 0},
+    {SelectionNotify, 0},
+    {SelectionRequest, 0},
+    {NoExpose, 0},
 };
 
 /**
@@ -95,790 +92,642 @@ static Client *pending=NULL;
 
 extern void
 dispatch(XEvent * ev) {
-       Disp * p;
-
-       for (p = disps; p < disps + sizeof(disps)/sizeof(disps[0]); p++) {
-               if (p->type == ev->type) {
-                       if (p->handler != 0)
-                               p->handler(ev);
-                       return;
-               }
-       }
-
-       if (!shapeEvent(ev))
-               fprintf(stderr, "%s: unknown event %d\n", argv0, ev->type);
+    Disp * p;
+
+    for (p = disps; p < disps + sizeof(disps)/sizeof(disps[0]); p++) {
+        if (p->type == ev->type) {
+            if (p->handler != 0)
+                p->handler(ev);
+            return;
+        }
+    }
+
+    fprintf(stderr, "%s: unknown event %d\n", argv0, ev->type);
 }
 
 static void
 expose(XEvent * ev) {
-       Client * c;
-       Window w;       /* Window the expose event is for. */
-
-       /* Only handle the last in a group of Expose events. */
-       if (ev->xexpose.count != 0) return;
-
-       w = ev->xexpose.window;
-
-       /*
-       * We don't draw on the root window so that people can have
-       * their favourite Spice Girls backdrop...
-       */
-       if (getScreenFromRoot(w) != 0)
-               return;
-
-       /* Decide what needs redrawing: window frame or menu? */
-       if (current_screen && w == current_screen->popup) {
-               if (mode == wm_reshaping && current != 0)
-                       size_expose();
-       } else {
-               c = Client_Get(w);
-               if (c != 0) {
-                       Client_DrawBorder(c, c == current);
-               }
-       }
+    Client * c;
+    Window w;   /* Window the expose event is for. */
+
+    /* Only handle the last in a group of Expose events. */
+    if (ev->xexpose.count != 0) return;
+
+    w = ev->xexpose.window;
+
+    /*
+    * We don't draw on the root window so that people can have
+    * their favourite Spice Girls backdrop...
+    */
+    if (getScreenFromRoot(w) != 0)
+        return;
+
+    /* redraw window frame */
+    c = Client_Get(w);
+    if (c != 0) {
+        Client_DrawFrame(c, c == current);
+    }
 }
 
 static void
 buttonpress(XEvent *ev) {
-       Client *c;
-       XButtonEvent *e = &ev->xbutton;
-       int quarter;
-
-       /* If we're getting it already, we're not in the market for more. */
-       if (mode != wm_idle) {
-               /* but allow a button press to cancel a move/resize,
-                * to satify the EWMH advisory to allow a second mechanism
-                * of completing move/resize operations, due to a race.
-                * (section 4.3) sucky!
-                */
-               if (mode == wm_reshaping) {
-                       mode = wm_idle;
-               }
-               return;
-       }
-
-       c = Client_Get(e->window);
-
-       if (c && c != current && focus_mode == focus_click) {
-               /* Click is not on current window,
-                * and in click-to-focus mode, so change focus
-                */
-               Client_Focus(c, e->time);
-       }
-
-       /*move this test up to disable scroll to focus*/
-       if (e->button >= 4 && e->button <= 7) {
-               return;
-       }
-
-       if (c && c == current && (e->window == c->parent)) {
-               /* Click went to our frame around a client. */
-
-               /* The ``box''. */
-               quarter = (border + titleHeight()) / 4;
-               if (e->x > (quarter + 2) && e->x < (3 + 3*quarter) && e->y > quarter && e->y <= 3*quarter) {
-                       /*Client_Close(c);*/
-                       pending = c;
-                       mode = wm_closing_window;
-                       return;
-               }
-
-               /* Somewhere in the rest of the frame. */
-               if (e->button == HIDE_BUTTON) {
-                       pending = c;
-                       mode = wm_hiding_window;
-                       return;
-               }
-               if (e->button == MOVE_BUTTON) {
-                       Client_Move(c);
-                       return;
-               }
-               if (e->button == RESHAPE_BUTTON) {
-                       XMapWindow(dpy, c->parent);
-                       Client_Raise(c);
-
-                       /* Lasciate ogni speranza voi ch'entrate...  */
-
-                       if (e->x <= border && e->y <= border) {
-                               Client_ReshapeEdge(c, ETopLeft);
-                       } else if (e->x >= (c->size.width - border) && e->y <= border) {
-                               Client_ReshapeEdge(c, ETopRight);
-                       } else if (e->x >= (c->size.width - border) && e->y >= (c->size.height + titleHeight() - border)) {
-                               Client_ReshapeEdge(c, EBottomRight);
-                       } else if (e->x <= border && e->y >= (c->size.height + titleHeight() - border)) {
-                               Client_ReshapeEdge(c, EBottomLeft);
-                       } else if (e->x > border && e->x < (c->size.width - border) && e->y < border) {
-                               Client_ReshapeEdge(c, ETop);
-                       } else if (e->x > border && e->x < (c->size.width - border) && e->y >= border && e->y < (titleHeight() + border)) {
-                               Client_Move(c);
-                       } else if (e->x > (c->size.width - border) && e->y > border && e->y < (c->size.height + titleHeight() - border)) {
-                               Client_ReshapeEdge(c, ERight);
-                       } else if (e->x > border && e->x < (c->size.width - border) && e->y > (c->size.height - border)) {
-                               Client_ReshapeEdge(c, EBottom);
-                       } else if (e->x < border && e->y > border && e->y < (c->size.height + titleHeight() - border)) {
-                               Client_ReshapeEdge(c, ELeft);
-                       }
-                       return;
-               }
-               return;
-       }
-
-       /* Deal with root window button presses. */
-       if (e->window == e->root) {
-               if (e->button == Button3) {
-                       cmapfocus(0);
-               } else {
-                       shell(getScreenFromRoot(e->root), e->button, e->x, e->y);
-               }
-       }
+    Client *c;
+    XButtonEvent *e = &ev->xbutton;
+    int quarter;
+
+    /* If we're getting it already, we're not in the market for more. */
+    if (mode != wm_idle) {
+        /* but allow a button press to cancel a move/resize,
+         * to satify the EWMH advisory to allow a second mechanism
+         * of completing move/resize operations, due to a race.
+         * (section 4.3) sucky!
+         */
+        if (mode == wm_reshaping) {
+            mode = wm_idle;
+        }
+        return;
+    }
+
+    c = Client_Get(e->window);
+
+    /*move this test up to disable scroll to focus*/
+    if (e->button >= 4 && e->button <= 7) {
+        return;
+    }
+
+    if (c && c == current && (e->window == c->parent)) {
+        /* Click went to our frame around a client. */
+        if (e->button == Button1) {
+            XMapWindow(dpy, c->parent);
+            Client_Raise(c);
+            if (e->x <= border && e->y <= border) {
+                Client_ReshapeEdge(c, ETopLeft);
+            } else if (e->x >= (c->size.width - border) && e->y <= border) {
+                Client_ReshapeEdge(c, ETopRight);
+            } else if (e->x >= (c->size.width - border) && e->y >= (c->size.height + titleHeight() - border)) {
+                Client_ReshapeEdge(c, EBottomRight);
+            } else if (e->x <= border && e->y >= (c->size.height + titleHeight() - border)) {
+                Client_ReshapeEdge(c, EBottomLeft);
+            } else if (e->x > border && e->x < (c->size.width - border) && e->y < border) {
+                Client_ReshapeEdge(c, ETop);
+            } else if (e->x > border && e->x < (c->size.width - border) && e->y >= border && e->y < (titleHeight() + border)) {
+                Client_Move(c);
+            } else if (e->x > (c->size.width - border) && e->y > border && e->y < (c->size.height + titleHeight() - border)) {
+                Client_ReshapeEdge(c, ERight);
+            } else if (e->x > border && e->x < (c->size.width - border) && e->y > (c->size.height - border)) {
+                Client_ReshapeEdge(c, EBottom);
+            } else if (e->x < border && e->y > border && e->y < (c->size.height + titleHeight() - border)) {
+                Client_ReshapeEdge(c, ELeft);
+            }
+            return;
+        } else if (e->button == Button2) {
+            Client_Close(c);
+        }
+        return;
+    }
 }
 
 static void
 buttonrelease(XEvent *ev) {
-       XButtonEvent *e = &ev->xbutton;
-       int quarter;
-
-       if (mode == wm_reshaping)
-               XUnmapWindow(dpy, current_screen->popup);
-       else if (mode == wm_closing_window) {
-               /* was the button released within the window's box?*/
-               quarter = (border + titleHeight()) / 4;
-               if (pending != NULL &&
-                       (e->window == pending->parent) &&
-                       (e->x > (quarter + 2) &&
-                               e->x < (3 + 3*quarter) &&
-                               e->y > quarter && e->y <= 3*quarter))
-                                       Client_Close(pending);
-               pending = NULL;
-       } else if (mode == wm_hiding_window) {
-               /* was the button release within the window's frame? */
-               if (pending != NULL &&
-                       (e->window == pending->parent) &&
-                       (e->x >= 0) && (e->y >= 0) &&
-                       (e->x <= pending->size.width) &&
-                       (e->y <= (pending->size.height + titleHeight()))) {
-                       if (e->state & ShiftMask) {
-                               Client_Lower(pending);
-                       }
-               }
-               pending = NULL;
-       }
-
-       mode = wm_idle;
+    mode = wm_idle;
 }
 
 static void circulaterequest(XEvent *ev) {
-       XCirculateRequestEvent * e = &ev->xcirculaterequest;
-       Client * c;
-
-       c = Client_Get(e->window);
-
-       if (c == 0) {
-               if (e->place == PlaceOnTop) {
-                       XRaiseWindow(e->display, e->window);
-               } else {
-                       XLowerWindow(e->display, e->window);
-               }
-       } else {
-               if (e->place == PlaceOnTop) {
-                       Client_Raise(c);
-               } else {
-                       Client_Lower(c);
-               }
-       }
+    XCirculateRequestEvent * e = &ev->xcirculaterequest;
+    Client * c = Client_Get(e->window);
+
+    if (c == 0) {
+        if (e->place == PlaceOnTop) {
+            XRaiseWindow(e->display, e->window);
+        } else {
+            XLowerWindow(e->display, e->window);
+        }
+    } else {
+        if (e->place == PlaceOnTop) {
+            Client_Raise(c);
+        } else {
+            Client_Lower(c);
+        }
+    }
 }
 
 static void
 maprequest(XEvent *ev) {
-       Client * c;
-       XMapRequestEvent * e = &ev->xmaprequest;
-
-       c = Client_Get(e->window);
-
-       if (c == 0 || c->window != e->window) {
-               int screen;
-               for (screen = 0; screen < screen_count; screen++)
-                       scanWindowTree(screen);
-               c = Client_Get(e->window);
-               if (c == 0 || c->window != e->window) {
-                       fprintf(stderr, "MapRequest for non-existent window!\n");
-                       return;
-               }
-       }
-
-       switch (c->state) {
-       case WithdrawnState:
-               if (getScreenFromRoot(c->parent) != 0) {
-                       manage(c, 0);
-                       break;
-               }
-               if (c->framed == True) {
-                       XReparentWindow(dpy, c->window, c->parent, border,
-                               border + titleHeight());
-               } else {
-                       XReparentWindow(dpy, c->window, c->parent,
-                               c->size.x, c->size.y);
-               }
-               XAddToSaveSet(dpy, c->window);
-               /*FALLTHROUGH*/
-       case NormalState:
-               XMapWindow(dpy, c->parent);
-               XMapWindow(dpy, c->window);
-               Client_Raise(c);
-               Client_SetState(c, NormalState);
-               break;
-       }
-       ewmh_set_client_list(c->screen);
+    Client * c;
+    XMapRequestEvent * e = &ev->xmaprequest;
+
+    c = Client_Get(e->window);
+
+    if (c == 0 || c->window != e->window) {
+        int screen;
+        for (screen = 0; screen < screen_count; screen++)
+            scanWindowTree(screen);
+        c = Client_Get(e->window);
+        if (c == 0 || c->window != e->window) {
+            fprintf(stderr, "MapRequest for non-existent window!\n");
+            return;
+        }
+    }
+
+    switch (c->state) {
+    case WithdrawnState:
+        if (getScreenFromRoot(c->parent) != 0) {
+            manage(c, 0);
+            break;
+        }
+        if (c->framed == True) {
+            XReparentWindow(dpy, c->window, c->parent, border,
+                border + titleHeight());
+        } else {
+            XReparentWindow(dpy, c->window, c->parent,
+                c->size.x, c->size.y);
+        }
+        XAddToSaveSet(dpy, c->window);
+        /*FALLTHROUGH*/
+    case NormalState:
+        XMapWindow(dpy, c->parent);
+        XMapWindow(dpy, c->window);
+        Client_Raise(c);
+        Client_SetState(c, NormalState);
+        break;
+    }
+    ewmh_set_client_list(c->screen);
 }
 
 static void
 unmap(XEvent *ev) {
-       Client *c;
-       XUnmapEvent *e = &ev->xunmap;
-
-       c = Client_Get(e->window);
-       if (c == 0) return;
-
-       /*
-        * In the description of the ReparentWindow request we read: "If the window
-        * is mapped, an UnmapWindow request is performed automatically first". This
-        * might seem stupid, but it's the way it is. While a reparenting is pending
-        * we ignore UnmapWindow requests.
-        */
-       if (c->internal_state == IPendingReparenting) {
-               c->internal_state = INormal;
-               return;
-       }
-
-       /* "This time it's the real thing." */
-
-       if (c->state == IconicState) {
-               /*
-                * Is this a hidden window disappearing? If not, then we
-                * aren't interested because it's an unmap request caused
-                * by our hiding a window.
-                */
-       } else {
-               /* This is a plain unmap, so withdraw the window. */
-               withdraw(c);
-       }
-
-       c->internal_state = INormal;
+    Client *c;
+    XUnmapEvent *e = &ev->xunmap;
+
+    c = Client_Get(e->window);
+    if (c == 0) return;
+
+    /*
+     * In the description of the ReparentWindow request we read: "If the window
+     * is mapped, an UnmapWindow request is performed automatically first". This
+     * might seem stupid, but it's the way it is. While a reparenting is pending
+     * we ignore UnmapWindow requests.
+     */
+    if (c->internal_state == IPendingReparenting) {
+        c->internal_state = INormal;
+        return;
+    }
+
+    /* This is a plain unmap, so withdraw the window. */
+    withdraw(c);
+
+    c->internal_state = INormal;
 }
 
 static void
 configurereq(XEvent *ev) {
-       XWindowChanges wc;
-       Client *c;
-       XConfigureRequestEvent *e = &ev->xconfigurerequest;
-
-       c = Client_Get(e->window);
-
-
-       if (c && c->window == e->window) {
-               /*
-               * ICCCM section 4.1.5 says that the x and y coordinates here
-               * will have been "adjusted for the border width".
-               * NOTE: this may not be the only place to bear this in mind.
-               */
-               if (e->value_mask & CWBorderWidth) {
-                       e->x -= e->border_width;
-                       e->y -= e->border_width;
-               } else {
-                       /*
-                       * The ICCCM also says that clients should always set the
-                       * border width in a configure request. As usual, many don't.
-                       */
-                       /* adding one seems a bit arbitrary and makes edit
-                               drift by one pixel*/
-                       /*e->x--;*/
-                       /*e->y--;*/
-               }
-
-               if (e->value_mask & CWX) {
-                       c->size.x = e->x;
-               }
-               if (e->value_mask & CWY) {
-                       c->size.y = e->y;
-                       if (c->framed == True)
-                               c->size.y += titleHeight();
-               }
-               if (e->value_mask & CWWidth) {
-                       c->size.width = e->width;
-                       if (c->framed == True)
-                               c->size.width += 2 * border;
-               }
-               if (e->value_mask & CWHeight) {
-                       c->size.height = e->height;
-                       if (c->framed == True)
-                               c->size.height += 2 * border;
-               }
-               if (e->value_mask & CWBorderWidth)
-                       c->border = e->border_width;
-
-               if (getScreenFromRoot(c->parent) == 0) {
-                       wc.x = c->size.x;
-                       wc.y = c->size.y;
-                       if (c->framed == True)
-                               wc.y -= titleHeight();
-                       wc.width = c->size.width;
-                       wc.height = c->size.height;
-                       if (c->framed == True)
-                               wc.height += titleHeight();
-                       wc.border_width = 1;
-                       wc.sibling = e->above;
-                       wc.stack_mode = e->detail;
-
-                       XConfigureWindow(dpy, e->parent, e->value_mask, &wc);
-                       sendConfigureNotify(c);
-               }
-       }
-       if (c && (c->internal_state == INormal) && (c->framed == True)) {
-               wc.x = border;
-               wc.y = border;
-       } else {
-               wc.x = e->x;
-               wc.y = e->y;
-       }
-
-       wc.width = e->width;
-       wc.height = e->height;
-       wc.border_width = 0;
-       wc.sibling = e->above;
-       wc.stack_mode = e->detail;
-       e->value_mask |= CWBorderWidth;
-
-       XConfigureWindow(dpy, e->window, e->value_mask, &wc);
-
-       if (c) {
-               if (c->framed == True)  {
-                       XMoveResizeWindow(dpy, c->parent,
-                               c->size.x, c->size.y - titleHeight(),
-                               c->size.width, c->size.height + titleHeight());
-                       XMoveWindow(dpy, c->window,
-                               border, border + titleHeight());
-               } else {
-                       XMoveResizeWindow(dpy, c->window,
-                               c->size.x, c->size.y,
-                               c->size.width, c->size.height);
-               }
-       }
+    XWindowChanges wc;
+    Client *c;
+    XConfigureRequestEvent *e = &ev->xconfigurerequest;
+
+    c = Client_Get(e->window);
+
+
+    if (c && c->window == e->window) {
+        /*
+        * ICCCM section 4.1.5 says that the x and y coordinates here
+        * will have been "adjusted for the border width".
+        * NOTE: this may not be the only place to bear this in mind.
+        */
+        if (e->value_mask & CWBorderWidth) {
+            e->x -= e->border_width;
+            e->y -= e->border_width;
+        } else {
+            /*
+            * The ICCCM also says that clients should always set the
+            * border width in a configure request. As usual, many don't.
+            */
+            /* adding one seems a bit arbitrary and makes edit
+                drift by one pixel*/
+            /*e->x--;*/
+            /*e->y--;*/
+        }
+
+        if (e->value_mask & CWX) {
+            c->size.x = e->x;
+        }
+        if (e->value_mask & CWY) {
+            c->size.y = e->y;
+            if (c->framed == True)
+                c->size.y += titleHeight();
+        }
+        if (e->value_mask & CWWidth) {
+            c->size.width = e->width;
+            if (c->framed == True)
+                c->size.width += 2 * border;
+        }
+        if (e->value_mask & CWHeight) {
+            c->size.height = e->height;
+            if (c->framed == True)
+                c->size.height += 2 * border;
+        }
+        if (e->value_mask & CWBorderWidth)
+            c->border = e->border_width;
+
+        if (getScreenFromRoot(c->parent) == 0) {
+            wc.x = c->size.x;
+            wc.y = c->size.y;
+            if (c->framed == True)
+                wc.y -= titleHeight();
+            wc.width = c->size.width;
+            wc.height = c->size.height;
+            if (c->framed == True)
+                wc.height += titleHeight();
+            wc.border_width = 1;
+            wc.sibling = e->above;
+            wc.stack_mode = e->detail;
+
+            XConfigureWindow(dpy, e->parent, e->value_mask, &wc);
+            sendConfigureNotify(c);
+        }
+    }
+    if (c && (c->internal_state == INormal) && (c->framed == True)) {
+        wc.x = border;
+        wc.y = border;
+    } else {
+        wc.x = e->x;
+        wc.y = e->y;
+    }
+
+    wc.width = e->width;
+    wc.height = e->height;
+    wc.border_width = 0;
+    wc.sibling = e->above;
+    wc.stack_mode = e->detail;
+    e->value_mask |= CWBorderWidth;
+
+    XConfigureWindow(dpy, e->window, e->value_mask, &wc);
+
+    if (c) {
+        if (c->framed == True)  {
+            XMoveResizeWindow(dpy, c->parent,
+                c->size.x, c->size.y - titleHeight(),
+                c->size.width, c->size.height + titleHeight());
+            XMoveWindow(dpy, c->window,
+                border, border + titleHeight());
+        } else {
+            XMoveResizeWindow(dpy, c->window,
+                c->size.x, c->size.y,
+                c->size.width, c->size.height);
+        }
+    }
 }
 
 static void
 destroy(XEvent *ev) {
-       Client * c;
-       Window w = ev->xdestroywindow.window;
+    Client * c;
+    Window w = ev->xdestroywindow.window;
 
-       c = Client_Get(w);
-       if (c == 0)
-               return;
+    c = Client_Get(w);
+    if (c == 0)
+        return;
 
-       ignore_badwindow = 1;
-       Client_Remove(c);
-       ignore_badwindow = 0;
+    ignore_badwindow = 1;
+    Client_Remove(c);
+    ignore_badwindow = 0;
 }
 
 static void
 clientmessage(XEvent *ev) {
-       Client * c;
-       XClientMessageEvent * e = &ev->xclient;
-
-       c = Client_Get(e->window);
-       if (c == 0) return;
-       if (e->message_type == wm_change_state) {
-               return;
-       }
-       if (e->message_type == ewmh_atom[_NET_WM_STATE] &&
-               e->format == 32) {
-               ewmh_change_state(c, e->data.l[0], e->data.l[1]);
-               ewmh_change_state(c, e->data.l[0], e->data.l[2]);
-               return;
-       }
-       if (e->message_type == ewmh_atom[_NET_ACTIVE_WINDOW] &&
-               e->format == 32) {
-               /* An EWMH enabled application has asked for this client
-                * to be made the active window. The window is raised, and
-                * focus given if the focus mode is click (focusing on a
-                * window other than the one the pointer is in makes no
-                * sense when the focus mode is enter).
-                */
-               XMapWindow(dpy, c->parent);
-               Client_Raise(c);
-               if (c != current && focus_mode == focus_click)
-                       Client_Focus(c, CurrentTime);
-               return;
-       }
-       if (e->message_type == ewmh_atom[_NET_CLOSE_WINDOW] &&
-               e->format == 32) {
-               Client_Close(c);
-               return;
-       }
-       if (e->message_type == ewmh_atom[_NET_MOVERESIZE_WINDOW] &&
-               e->format == 32) {
-               XEvent ev;
-
-               /* FIXME: ok, so this is a bit of a hack */
-               ev.xconfigurerequest.window = e->window;
-               ev.xconfigurerequest.x = e->data.l[1];
-               ev.xconfigurerequest.y = e->data.l[2];
-               ev.xconfigurerequest.width = e->data.l[3];
-               ev.xconfigurerequest.height = e->data.l[4];
-               ev.xconfigurerequest.value_mask = 0;
-               if (e->data.l[0] & (1 << 8))
-                       ev.xconfigurerequest.value_mask |= CWX;
-               if (e->data.l[0] & (1 << 9))
-                       ev.xconfigurerequest.value_mask |= CWY;
-               if (e->data.l[0] & (1 << 10))
-                       ev.xconfigurerequest.value_mask |= CWWidth;
-               if (e->data.l[0] & (1 << 11))
-                       ev.xconfigurerequest.value_mask |= CWHeight;
-               configurereq(&ev);
-               return;
-       }
-       if (e->message_type == ewmh_atom[_NET_WM_MOVERESIZE] &&
-               e->format == 32) {
-               Edge edge = E_LAST;
-               EWMHDirection direction = e->data.l[2];
-/*
-               int x_root = e->data.l[0];
-               int y_root = e->data.l[1];
-*/
-
-
-               /* before we can do any resizing, make the window visible */
-               XMapWindow(dpy, c->parent);
-               Client_Raise(c);
-               /* FIXME: we're ignorning x_root, y_root and button! */
-               switch (direction) {
-               case DSizeTopLeft:
-                       edge = ETopLeft;
-                       break;
-               case DSizeTop:
-                       edge = ETop;
-                       break;
-               case DSizeTopRight:
-                       edge = ETopRight;
-                       break;
-               case DSizeRight:
-                       edge = ERight;
-                       break;
-               case DSizeBottomRight:
-                       edge = EBottomRight;
-                       break;
-               case DSizeBottom:
-                       edge = EBottom;
-                       break;
-               case DSizeBottomLeft:
-                       edge = EBottomLeft;
-                       break;
-               case DSizeLeft:
-                       edge = ELeft;
-                       break;
-               case DMove:
-                       edge = ENone;
-                       break;
-               case DSizeKeyboard:
-                       /* FIXME: don't know how to deal with this */
-                       edge = E_LAST;
-                       break;
-               case DMoveKeyboard:
-#if 0
-/* need to do a release and this is too broken for that */
-                       /* don't believe i'm doing this. mouse warping
-                        * sucks!
-                        */
-                       XWarpPointer(dpy, c->screen->root, c->window,
-                               x_root, y_root,
-                               c->screen->display_width,
-                               c->screen->display_height,
-                               c->size.width / 2, c->size.height / 2);
-                       edge = ENone;
-#endif
-                       edge = E_LAST;
-                       break;
-               default:
-                       edge = E_LAST;
-                       fprintf(stderr, "%s: received _NET_WM_MOVERESIZE"
-                               " with bad direction", argv0);
-                       break;
-               }
-               switch (edge) {
-               case E_LAST:
-                       break;
-               case ENone:
-                       Client_Move(c);
-                       break;
-               default:
-                       Client_ReshapeEdge(c, edge);
-                       break;
-               }
-       }
-}
-
-static void
-colormap(XEvent *ev) {
-       Client * c;
-       XColormapEvent * e = &ev->xcolormap;
-
-       if (e->new) {
-               c = Client_Get(e->window);
-               if (c) {
-                       c->cmap = e->colormap;
-                       if (c == current)
-                               cmapfocus(c);
-               } else {
-                       Client_ColourMap(ev);
-               }
-       }
+    Client * c;
+    XClientMessageEvent * e = &ev->xclient;
+
+    c = Client_Get(e->window);
+    if (c == 0) return;
+    if (e->message_type == ewmh_atom[_NET_ACTIVE_WINDOW] &&
+        e->format == 32) {
+        /* An EWMH enabled application has asked for this client
+         * to be made the active window. The window is raised, and
+         * focus given if the focus mode is click (focusing on a
+         * window other than the one the pointer is in makes no
+         * sense when the focus mode is enter).
+         */
+        XMapWindow(dpy, c->parent);
+        Client_Raise(c);
+        return;
+    }
+    if (e->message_type == ewmh_atom[_NET_CLOSE_WINDOW] &&
+        e->format == 32) {
+        Client_Close(c);
+        return;
+    }
+    if (e->message_type == ewmh_atom[_NET_MOVERESIZE_WINDOW] &&
+        e->format == 32) {
+        XEvent ev;
+
+        /* FIXME: ok, so this is a bit of a hack */
+        ev.xconfigurerequest.window = e->window;
+        ev.xconfigurerequest.x = e->data.l[1];
+        ev.xconfigurerequest.y = e->data.l[2];
+        ev.xconfigurerequest.width = e->data.l[3];
+        ev.xconfigurerequest.height = e->data.l[4];
+        ev.xconfigurerequest.value_mask = 0;
+        if (e->data.l[0] & (1 << 8))
+            ev.xconfigurerequest.value_mask |= CWX;
+        if (e->data.l[0] & (1 << 9))
+            ev.xconfigurerequest.value_mask |= CWY;
+        if (e->data.l[0] & (1 << 10))
+            ev.xconfigurerequest.value_mask |= CWWidth;
+        if (e->data.l[0] & (1 << 11))
+            ev.xconfigurerequest.value_mask |= CWHeight;
+        configurereq(&ev);
+        return;
+    }
+    if (e->message_type == ewmh_atom[_NET_WM_MOVERESIZE] &&
+        e->format == 32) {
+        Edge edge = E_LAST;
+        EWMHDirection direction = e->data.l[2];
+
+        /* before we can do any resizing, make the window visible */
+        XMapWindow(dpy, c->parent);
+        Client_Raise(c);
+        /* FIXME: we're ignorning x_root, y_root and button! */
+        switch (direction) {
+        case DSizeTopLeft:
+            edge = ETopLeft;
+            break;
+        case DSizeTop:
+            edge = ETop;
+            break;
+        case DSizeTopRight:
+            edge = ETopRight;
+            break;
+        case DSizeRight:
+            edge = ERight;
+            break;
+        case DSizeBottomRight:
+            edge = EBottomRight;
+            break;
+        case DSizeBottom:
+            edge = EBottom;
+            break;
+        case DSizeBottomLeft:
+            edge = EBottomLeft;
+            break;
+        case DSizeLeft:
+            edge = ELeft;
+            break;
+        case DMove:
+            edge = ENone;
+            break;
+        case DSizeKeyboard:
+            /* FIXME: don't know how to deal with this */
+            edge = E_LAST;
+            break;
+        case DMoveKeyboard:
+            edge = E_LAST;
+            break;
+        default:
+            edge = E_LAST;
+            fprintf(stderr, "%s: received _NET_WM_MOVERESIZE"
+                " with bad direction", argv0);
+            break;
+        }
+        switch (edge) {
+        case E_LAST:
+            break;
+        case ENone:
+            Client_Move(c);
+            break;
+        default:
+            Client_ReshapeEdge(c, edge);
+            break;
+        }
+    }
 }
 
 static void
 property(XEvent * ev) {
-       Client * c;
-       XPropertyEvent * e = &ev->xproperty;
-
-       c = Client_Get(e->window);
-       if (c == 0)
-               return;
-
-       if (e->atom == _mozilla_url || e->atom == XA_WM_NAME) {
-               getWindowName(c);
-               setactive(c, c == current, 0L);
-       } else if (e->atom == XA_WM_TRANSIENT_FOR) {
-               getTransientFor(c);
-       } else if (e->atom == XA_WM_NORMAL_HINTS) {
-               getNormalHints(c);
-       } else if (e->atom == wm_colormaps) {
-               getColourmaps(c);
-               if (c == current)
-                       cmapfocus(c);
-       } else if (e->atom == ewmh_atom[_NET_WM_STRUT]) {
-               ewmh_get_strut(c);
-       } else if (e->atom == ewmh_atom[_NET_WM_STATE]) {
-               // Received notice that client wants to change its state
-               //  update internal wstate tracking
-               Bool wasFullscreen = c->wstate.fullscreen;
-               ewmh_get_state(c);
-               // make any changes requested
-               if (c->wstate.fullscreen == True && wasFullscreen == False) Client_EnterFullScreen(c);
-               else if (c->wstate.fullscreen == False && wasFullscreen == True) Client_ExitFullScreen(c);
-       }
+    Client * c;
+    XPropertyEvent * e = &ev->xproperty;
+
+    c = Client_Get(e->window);
+    if (c == 0)
+        return;
+
+    if (e->atom == XA_WM_NAME) {
+        getWindowName(c);
+        Client_SetActive(c, c == current, 0L);
+    } else if (e->atom == XA_WM_TRANSIENT_FOR) {
+        getTransientFor(c);
+    } else if (e->atom == XA_WM_NORMAL_HINTS) {
+        getNormalHints(c);
+    }
 }
 
 static void
 reparent(XEvent *ev) {
-       Client * c;
-       XReparentEvent * e = &ev->xreparent;
+    Client * c;
+    XReparentEvent * e = &ev->xreparent;
 
-       if (getScreenFromRoot(e->event) == 0 || e->override_redirect || getScreenFromRoot(e->parent) != 0)
-               return;
+    if (getScreenFromRoot(e->event) == 0 || e->override_redirect || getScreenFromRoot(e->parent) != 0)
+        return;
 
-       c = Client_Get(e->window);
-       if (c != 0 && (getScreenFromRoot(c->parent) != 0 || withdrawn(c)))
-               Client_Remove(c);
+    c = Client_Get(e->window);
+    if (c != 0 && (getScreenFromRoot(c->parent) != 0 || Client_IsState(c, WithdrawnState)))
+        Client_Remove(c);
 }
 
 static void
 focuschange(XEvent *ev) {
-       Client *c;
-       Window focus_window;
-       int revert_to;
-
-       if (ev->type == FocusOut) return;
-
-       XGetInputFocus(dpy, &focus_window, &revert_to);
-       if (focus_window == PointerRoot || focus_window == None) {
-               if (current) Client_Focus(NULL, CurrentTime);
-               return;
-       }
-       c = Client_Get(focus_window);
-       if (c && c != current) {
-               Client_Focus(c, CurrentTime);
-       }
-       return;
+    Client *c;
+    Window focus_window;
+    int revert_to;
+
+    if (ev->type == FocusOut) return;
+
+    XGetInputFocus(dpy, &focus_window, &revert_to);
+    if (focus_window == PointerRoot || focus_window == None) {
+        if (current) Client_Focus(NULL, CurrentTime);
+        return;
+    }
+    c = Client_Get(focus_window);
+    if (c && c != current) {
+        Client_Focus(c, CurrentTime);
+    }
+    return;
 }
 
 static void
 enter(XEvent *ev) {
-       Client *c;
-
-       c = Client_Get(ev->xcrossing.window);
-       if (c == 0 || mode != wm_idle)
-               return;
-
-       if (c->framed == True) {
-               XSetWindowAttributes attr;
-
-               attr.cursor = c->screen->root_cursor;
-               XChangeWindowAttributes(dpy, c->parent,
-                       CWCursor, &attr);
-               c->cursor = ENone;
-       }
-       if (c != current && !c->hidden && focus_mode == focus_enter) {
-               /* Entering a new window in enter focus mode, so take focus */
-               Client_Focus(c, ev->xcrossing.time);
-       }
+    Client *c;
+
+    c = Client_Get(ev->xcrossing.window);
+    if (c == 0 || mode != wm_idle)
+        return;
+
+    if (c->framed == True) {
+        XSetWindowAttributes attr;
+
+        attr.cursor = c->screen->root_cursor;
+        XChangeWindowAttributes(dpy, c->parent,
+            CWCursor, &attr);
+        c->cursor = ENone;
+    }
+    if (c != current) {
+        /* Entering a new window in enter focus mode, so take focus */
+        Client_Focus(c, ev->xcrossing.time);
+    }
 }
 
 static void
 motionnotify(XEvent *ev) {
-       if (mode == wm_reshaping)
-               reshaping_motionnotify(ev);
-       else if (mode == wm_idle) {
-               XMotionEvent *e = &ev->xmotion;
-               Client *c = Client_Get(e->window);
-               Edge edge = ENone;
-               int quarter = (border + titleHeight()) / 4;
-
-               if (c && (e->window == c->parent) &&
-                       (e->subwindow != c->window) &&
-                       mode == wm_idle) {
-                       /* mouse moved in a frame we manage - check cursor */
-                       if (e->x > (quarter + 2)
-                               && e->x < (3 + 3*quarter)
-                               && e->y > quarter && e->y <= 3*quarter) {
-                               edge = E_LAST;
-                       } else if (e->x <= border && e->y <= border) {
-                               edge = ETopLeft;
-                       } else if (e->x >= (c->size.width - border)
-                               && e->y <= border) {
-                               edge = ETopRight;
-                       } else if (e->x >= (c->size.width - border)
-                               && e->y >=
-                               (c->size.height + titleHeight() - border)) {
-                               edge = EBottomRight;
-                       } else if (e->x <= border &&
-                               e->y >=
-                               (c->size.height + titleHeight() - border)) {
-                               edge = EBottomLeft;
-                       } else if (e->x > border &&
-                               e->x < (c->size.width - border)
-                               && e->y < border) {
-                               edge = ETop;
-                       } else if (e->x > border &&
-                               e->x < (c->size.width - border)
-                               && e->y >= border
-                               && e->y < (titleHeight() + border)) {
-                               edge = ENone;
-                       } else if (e->x > (c->size.width - border)
-                               && e->y > border
-                               && e->y <
-                               (c->size.height + titleHeight() - border)) {
-                               edge = ERight;
-                       } else if (e->x > border
-                               && e->x < (c->size.width - border)
-                               && e->y > (c->size.height - border)) {
-                               edge = EBottom;
-                       } else if (e->x < border
-                               && e->y > border
-                               && e->y <
-                               (c->size.height + titleHeight() - border)) {
-                               edge = ELeft;
-                       }
-                       if (c->cursor != edge) {
-                               XSetWindowAttributes attr;
-
-                               if (edge == ENone) {
-                                       attr.cursor =
-                                               c->screen->root_cursor;
-                               } else if (edge == E_LAST) {
-                                       attr.cursor =
-                                               c->screen->box_cursor;
-                               } else {
-                                       attr.cursor =
-                                               c->screen->cursor_map[edge];
-                               }
-                               XChangeWindowAttributes(dpy, c->parent,
-                                       CWCursor, &attr);
-                               c->cursor = edge;
-                       }
-               }
-       }
+    if (mode == wm_reshaping)
+        reshaping_motionnotify(ev);
+    else if (mode == wm_idle) {
+        XMotionEvent *e = &ev->xmotion;
+        Client *c = Client_Get(e->window);
+        Edge edge = ENone;
+        int quarter = (border + titleHeight()) / 4;
+
+        if (c && (e->window == c->parent) &&
+            (e->subwindow != c->window) &&
+            mode == wm_idle) {
+            /* mouse moved in a frame we manage - check cursor */
+            if (e->x > (quarter + 2)
+                && e->x < (3 + 3*quarter)
+                && e->y > quarter && e->y <= 3*quarter) {
+                edge = E_LAST;
+            } else if (e->x <= border && e->y <= border) {
+                edge = ETopLeft;
+            } else if (e->x >= (c->size.width - border)
+                && e->y <= border) {
+                edge = ETopRight;
+            } else if (e->x >= (c->size.width - border)
+                && e->y >=
+                (c->size.height + titleHeight() - border)) {
+                edge = EBottomRight;
+            } else if (e->x <= border &&
+                e->y >=
+                (c->size.height + titleHeight() - border)) {
+                edge = EBottomLeft;
+            } else if (e->x > border &&
+                e->x < (c->size.width - border)
+                && e->y < border) {
+                edge = ETop;
+            } else if (e->x > border &&
+                e->x < (c->size.width - border)
+                && e->y >= border
+                && e->y < (titleHeight() + border)) {
+                edge = ENone;
+            } else if (e->x > (c->size.width - border)
+                && e->y > border
+                && e->y <
+                (c->size.height + titleHeight() - border)) {
+                edge = ERight;
+            } else if (e->x > border
+                && e->x < (c->size.width - border)
+                && e->y > (c->size.height - border)) {
+                edge = EBottom;
+            } else if (e->x < border
+                && e->y > border
+                && e->y <
+                (c->size.height + titleHeight() - border)) {
+                edge = ELeft;
+            }
+            if (c->cursor != edge) {
+                XSetWindowAttributes attr;
+
+                if (edge == ENone) {
+                    attr.cursor = c->screen->root_cursor;
+                } else {
+                    attr.cursor = c->screen->cursor_map[edge];
+                }
+                XChangeWindowAttributes(dpy, c->parent,
+                    CWCursor, &attr);
+                c->cursor = edge;
+            }
+        }
+    }
 }
 
 /*ARGSUSED*/
-void
+static void
 reshaping_motionnotify(XEvent* ev) {
-       int     nx;     /* New x. */
-       int     ny;     /* New y. */
-       int     ox;     /* Original x. */
-       int     oy;     /* Original y. */
-       int     ndx;    /* New width. */
-       int     ndy;    /* New height. */
-       int     odx;    /* Original width. */
-       int     ody;    /* Original height. */
-       int     pointer_x;
-       int     pointer_y;
-
-       if (mode != wm_reshaping || !current) return;
-
-       getMousePosition(&pointer_x, &pointer_y);
-
-       if (interacting_edge != ENone) {
-               nx = ox = current->size.x;
-               ny = oy = current->size.y;
-               ndx = odx = current->size.width;
-               ndy = ody = current->size.height;
-
-               /* Vertical. */
-               switch (interacting_edge) {
-               case ETop:
-               case ETopLeft:
-               case ETopRight:
-                       pointer_y += titleHeight();
-                       ndy += (current->size.y - pointer_y);
-                       ny = pointer_y;
-                       break;
-               case EBottom:
-               case EBottomLeft:
-               case EBottomRight:
-                       ndy = pointer_y - current->size.y;
-                       break;
-               default:        break;
-               }
-
-               /* Horizontal. */
-               switch (interacting_edge) {
-               case ERight:
-               case ETopRight:
-               case EBottomRight:
-                       ndx = pointer_x - current->size.x;
-                       break;
-               case ELeft:
-               case ETopLeft:
-               case EBottomLeft:
-                       ndx += (current->size.x - pointer_x);
-                       nx = pointer_x;
-                       break;
-               default: break;
-               }
-
-               Client_MakeSane(current, interacting_edge, &nx, &ny, &ndx, &ndy);
-               XMoveResizeWindow(dpy, current->parent,
-                       current->size.x, current->size.y - titleHeight(),
-                       current->size.width, current->size.height + titleHeight());
-               if (current->size.width == odx && current->size.height == ody) {
-                       if (current->size.x != ox || current->size.y != oy)
-                               sendConfigureNotify(current);
-               } else
-                       XMoveResizeWindow(dpy, current->window,
-                               border, border + titleHeight(),
-                               current->size.width - 2 * border,
-                               current->size.height - 2 * border);
-       } else {
-               nx = pointer_x + start_x;
-               ny = pointer_y + start_y;
-
-               Client_MakeSane(current, interacting_edge, &nx, &ny, 0, 0);
-               if (current->framed == True) {
-                       XMoveWindow(dpy, current->parent,
-                               current->size.x,
-                               current->size.y - titleHeight());
-               } else {
-                       XMoveWindow(dpy, current->parent,
-                               current->size.x, current->size.y);
-               }
-               sendConfigureNotify(current);
-       }
+    int nx; /* New x. */
+    int ny; /* New y. */
+    int ox; /* Original x. */
+    int oy; /* Original y. */
+    int ndx;    /* New width. */
+    int ndy;    /* New height. */
+    int odx;    /* Original width. */
+    int ody;    /* Original height. */
+    int pointer_x;
+    int pointer_y;
+
+    if (mode != wm_reshaping || !current) return;
+
+    getMousePosition(&pointer_x, &pointer_y);
+
+    if (interacting_edge != ENone) {
+        nx = ox = current->size.x;
+        ny = oy = current->size.y;
+        ndx = odx = current->size.width;
+        ndy = ody = current->size.height;
+
+        /* Vertical. */
+        switch (interacting_edge) {
+        case ETop:
+        case ETopLeft:
+        case ETopRight:
+            pointer_y += titleHeight();
+            ndy += (current->size.y - pointer_y);
+            ny = pointer_y;
+            break;
+        case EBottom:
+        case EBottomLeft:
+        case EBottomRight:
+            ndy = pointer_y - current->size.y;
+            break;
+        default:    break;
+        }
+
+        /* Horizontal. */
+        switch (interacting_edge) {
+        case ERight:
+        case ETopRight:
+        case EBottomRight:
+            ndx = pointer_x - current->size.x;
+            break;
+        case ELeft:
+        case ETopLeft:
+        case EBottomLeft:
+            ndx += (current->size.x - pointer_x);
+            nx = pointer_x;
+            break;
+        default: break;
+        }
+
+        Client_MakeSane(current, interacting_edge, &nx, &ny, &ndx, &ndy);
+        XMoveResizeWindow(dpy, current->parent,
+            current->size.x, current->size.y - titleHeight(),
+            current->size.width, current->size.height + titleHeight());
+        if (current->size.width == odx && current->size.height == ody) {
+            if (current->size.x != ox || current->size.y != oy)
+                sendConfigureNotify(current);
+        } else
+            XMoveResizeWindow(dpy, current->window,
+                border, border + titleHeight(),
+                current->size.width - 2 * border,
+                current->size.height - 2 * border);
+    } else {
+        nx = pointer_x + start_x;
+        ny = pointer_y + start_y;
+
+        Client_MakeSane(current, interacting_edge, &nx, &ny, 0, 0);
+        if (current->framed == True) {
+            XMoveWindow(dpy, current->parent,
+                current->size.x,
+                current->size.y - titleHeight());
+        } else {
+            XMoveWindow(dpy, current->parent,
+                current->size.x, current->size.y);
+        }
+        sendConfigureNotify(current);
+    }
 }
diff --git a/ewmh.c b/ewmh.c
index e6bb1b3f42138aa11d6c8442a81cd4b85ba3ec27..54f1b7465c16c3a7b0574c4c8c8471d324880417 100644 (file)
--- a/ewmh.c
+++ b/ewmh.c
@@ -1,17 +1,17 @@
 /*
  * lwm, a window manager for X11
  * Copyright (C) 1997-2016 Elliott Hughes, James Carter
- * 
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -34,376 +34,248 @@ Atom utf8_string;
 
 void
 ewmh_init(void) {
-       /* build half a million EWMH atoms */
-       ewmh_atom[_NET_SUPPORTED] =
-               XInternAtom(dpy, "_NET_SUPPORTED", False);
-       ewmh_atom[_NET_CLIENT_LIST] =
-               XInternAtom(dpy, "_NET_CLIENT_LIST", False);
-       ewmh_atom[_NET_CLIENT_LIST_STACKING] =
-               XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
-       ewmh_atom[_NET_NUMBER_OF_DESKTOPS] =
-               XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
-       ewmh_atom[_NET_DESKTOP_GEOMETRY] =
-               XInternAtom(dpy, "_NET_DESKTOP_GEOMETRY", False);
-       ewmh_atom[_NET_DESKTOP_VIEWPORT] =
-               XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
-       ewmh_atom[_NET_CURRENT_DESKTOP] =
-               XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
-       ewmh_atom[_NET_ACTIVE_WINDOW] =
-               XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
-       ewmh_atom[_NET_WORKAREA] =
-               XInternAtom(dpy, "_NET_WORKAREA", False);
-       ewmh_atom[_NET_SUPPORTING_WM_CHECK] =
-               XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
-       ewmh_atom[_NET_CLOSE_WINDOW] =
-               XInternAtom(dpy, "_NET_CLOSE_WINDOW", False);
-       ewmh_atom[_NET_MOVERESIZE_WINDOW] =
-               XInternAtom(dpy, "_NET_MOVERESIZE_WINDOW", False);
-       ewmh_atom[_NET_WM_MOVERESIZE] =
-               XInternAtom(dpy, "_NET_WM_MOVERESIZE", False);
-       ewmh_atom[_NET_WM_NAME] =
-               XInternAtom(dpy, "_NET_WM_NAME", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
-       ewmh_atom[_NET_WM_STATE] =
-               XInternAtom(dpy, "_NET_WM_STATE", False);
-       ewmh_atom[_NET_WM_ALLOWED_ACTIONS] =
-               XInternAtom(dpy, "_NET_WM_ALLOWED_ACTIONS", False);
-       ewmh_atom[_NET_WM_STRUT] =
-               XInternAtom(dpy, "_NET_WM_STRUT", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_DESKTOP] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_DOCK] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_TOOLBAR] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_MENU] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_UTILITY] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_UTILITY", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_SPLASH] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_DIALOG] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
-       ewmh_atom[_NET_WM_WINDOW_TYPE_NORMAL] =
-               XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);
-       ewmh_atom[_NET_WM_STATE_SKIP_TASKBAR] =
-               XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
-       ewmh_atom[_NET_WM_STATE_SKIP_PAGER] =
-               XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
-       ewmh_atom[_NET_WM_STATE_HIDDEN] =
-               XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
-       ewmh_atom[_NET_WM_STATE_FULLSCREEN] =
-               XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
-       ewmh_atom[_NET_WM_ACTION_MOVE] =
-               XInternAtom(dpy, "_NET_WM_ACTION_MOVE", False);
-       ewmh_atom[_NET_WM_ACTION_RESIZE] =
-               XInternAtom(dpy, "_NET_WM_ACTION_RESIZE", False);
-       ewmh_atom[_NET_WM_ACTION_FULLSCREEN] =
-               XInternAtom(dpy, "_NET_WM_ACTION_FULLSCREEN", False);
-       ewmh_atom[_NET_WM_ACTION_CLOSE] =
-               XInternAtom(dpy, "_NET_WM_ACTION_CLOSE", False);
-       utf8_string = XInternAtom(dpy, "UTF8_STRING", False);
+    /* build half a million EWMH atoms */
+    ewmh_atom[_NET_SUPPORTED] =
+        XInternAtom(dpy, "_NET_SUPPORTED", False);
+    ewmh_atom[_NET_CLIENT_LIST] =
+        XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+    ewmh_atom[_NET_CLIENT_LIST_STACKING] =
+        XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
+    ewmh_atom[_NET_NUMBER_OF_DESKTOPS] =
+        XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
+    ewmh_atom[_NET_DESKTOP_GEOMETRY] =
+        XInternAtom(dpy, "_NET_DESKTOP_GEOMETRY", False);
+    ewmh_atom[_NET_DESKTOP_VIEWPORT] =
+        XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
+    ewmh_atom[_NET_CURRENT_DESKTOP] =
+        XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
+    ewmh_atom[_NET_ACTIVE_WINDOW] =
+        XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
+    ewmh_atom[_NET_WORKAREA] =
+        XInternAtom(dpy, "_NET_WORKAREA", False);
+    ewmh_atom[_NET_SUPPORTING_WM_CHECK] =
+        XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
+    ewmh_atom[_NET_CLOSE_WINDOW] =
+        XInternAtom(dpy, "_NET_CLOSE_WINDOW", False);
+    ewmh_atom[_NET_MOVERESIZE_WINDOW] =
+        XInternAtom(dpy, "_NET_MOVERESIZE_WINDOW", False);
+    ewmh_atom[_NET_WM_MOVERESIZE] =
+        XInternAtom(dpy, "_NET_WM_MOVERESIZE", False);
+    ewmh_atom[_NET_WM_NAME] =
+        XInternAtom(dpy, "_NET_WM_NAME", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
+    ewmh_atom[_NET_WM_STATE] =
+        XInternAtom(dpy, "_NET_WM_STATE", False);
+    ewmh_atom[_NET_WM_ALLOWED_ACTIONS] =
+        XInternAtom(dpy, "_NET_WM_ALLOWED_ACTIONS", False);
+    ewmh_atom[_NET_WM_STRUT] =
+        XInternAtom(dpy, "_NET_WM_STRUT", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_DESKTOP] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_DOCK] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_TOOLBAR] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_MENU] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_UTILITY] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_UTILITY", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_SPLASH] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_DIALOG] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+    ewmh_atom[_NET_WM_WINDOW_TYPE_NORMAL] =
+        XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);
+    ewmh_atom[_NET_WM_STATE_SKIP_TASKBAR] =
+        XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
+    ewmh_atom[_NET_WM_STATE_SKIP_PAGER] =
+        XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
+    ewmh_atom[_NET_WM_STATE_HIDDEN] =
+        XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
+    ewmh_atom[_NET_WM_STATE_FULLSCREEN] =
+        XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+    ewmh_atom[_NET_WM_ACTION_MOVE] =
+        XInternAtom(dpy, "_NET_WM_ACTION_MOVE", False);
+    ewmh_atom[_NET_WM_ACTION_RESIZE] =
+        XInternAtom(dpy, "_NET_WM_ACTION_RESIZE", False);
+    ewmh_atom[_NET_WM_ACTION_FULLSCREEN] =
+        XInternAtom(dpy, "_NET_WM_ACTION_FULLSCREEN", False);
+    ewmh_atom[_NET_WM_ACTION_CLOSE] =
+        XInternAtom(dpy, "_NET_WM_ACTION_CLOSE", False);
+    utf8_string = XInternAtom(dpy, "UTF8_STRING", False);
 }
 
 void
 ewmh_init_screens(void) {
-       int i;
-       unsigned long data[4];
-
-       /* announce EWMH compatibility on all acreens */
-       for (i = 0; i < screen_count; i++) {
-               screens[i].ewmh_set_client_list = False;
-               screens[i].ewmh_compat = XCreateSimpleWindow(dpy,
-                       screens[i].root,
-                       -200, -200, 1, 1, 
-                       0, 0, 0);
-               XChangeProperty(dpy, screens[i].ewmh_compat,
-                       ewmh_atom[_NET_WM_NAME],
-                       utf8_string, 8, PropModeReplace,
-                       "lwm", 3);
-
-               /* set root window properties */
-               XChangeProperty(dpy, screens[i].root,
-                       ewmh_atom[_NET_SUPPORTED],
-                       XA_ATOM, 32, PropModeReplace,
-                       (unsigned char *)ewmh_atom, EWMH_ATOM_LAST);
-
-               XChangeProperty(dpy, screens[i].root,
-                       ewmh_atom[_NET_SUPPORTING_WM_CHECK],
-                       XA_WINDOW, 32, PropModeReplace,
-                       (unsigned char *)&screens[i].ewmh_compat, 1);
-
-               data[0] = 1;
-               XChangeProperty(dpy, screens[i].root,
-                       ewmh_atom[_NET_NUMBER_OF_DESKTOPS],
-                       XA_CARDINAL, 32, PropModeReplace,
-                       (unsigned char*)data, 1);
-
-               data[0] = screens[i].display_width;
-               data[1] = screens[i].display_height;
-               XChangeProperty(dpy, screens[i].root,
-                       ewmh_atom[_NET_DESKTOP_GEOMETRY],
-                       XA_CARDINAL, 32, PropModeReplace,
-                       (unsigned char*)data, 2);
-
-               data[0] = 0;
-               data[1] = 0;
-               XChangeProperty(dpy, screens[i].root,
-                       ewmh_atom[_NET_DESKTOP_VIEWPORT],
-                       XA_CARDINAL, 32, PropModeReplace,
-                       (unsigned char*)data, 2);
-
-               data[0] = 0;
-               XChangeProperty(dpy, screens[i].root,
-                       ewmh_atom[_NET_CURRENT_DESKTOP],
-                       XA_CARDINAL, 32, PropModeReplace,
-                       (unsigned char*)data, 1);
-
-               ewmh_set_strut(&screens[i]);
-               ewmh_set_client_list(&screens[i]);
-       }
+    int i;
+    unsigned long data[4];
+
+    /* announce EWMH compatibility on all acreens */
+    for (i = 0; i < screen_count; i++) {
+        screens[i].ewmh_set_client_list = False;
+        screens[i].ewmh_compat = XCreateSimpleWindow(dpy,
+            screens[i].root,
+            -200, -200, 1, 1,
+            0, 0, 0);
+        XChangeProperty(dpy, screens[i].ewmh_compat,
+            ewmh_atom[_NET_WM_NAME],
+            utf8_string, 8, PropModeReplace,
+            (unsigned char*)"lwm", 3);
+
+        /* set root window properties */
+        XChangeProperty(dpy, screens[i].root,
+            ewmh_atom[_NET_SUPPORTED],
+            XA_ATOM, 32, PropModeReplace,
+            (unsigned char *)ewmh_atom, EWMH_ATOM_LAST);
+
+        XChangeProperty(dpy, screens[i].root,
+            ewmh_atom[_NET_SUPPORTING_WM_CHECK],
+            XA_WINDOW, 32, PropModeReplace,
+            (unsigned char *)&screens[i].ewmh_compat, 1);
+
+        data[0] = 1;
+        XChangeProperty(dpy, screens[i].root,
+            ewmh_atom[_NET_NUMBER_OF_DESKTOPS],
+            XA_CARDINAL, 32, PropModeReplace,
+            (unsigned char*)data, 1);
+
+        data[0] = screens[i].display_width;
+        data[1] = screens[i].display_height;
+        XChangeProperty(dpy, screens[i].root,
+            ewmh_atom[_NET_DESKTOP_GEOMETRY],
+            XA_CARDINAL, 32, PropModeReplace,
+            (unsigned char*)data, 2);
+
+        data[0] = 0;
+        data[1] = 0;
+        XChangeProperty(dpy, screens[i].root,
+            ewmh_atom[_NET_DESKTOP_VIEWPORT],
+            XA_CARDINAL, 32, PropModeReplace,
+            (unsigned char*)data, 2);
+
+        data[0] = 0;
+        XChangeProperty(dpy, screens[i].root,
+            ewmh_atom[_NET_CURRENT_DESKTOP],
+            XA_CARDINAL, 32, PropModeReplace,
+            (unsigned char*)data, 1);
+
+        ewmh_set_client_list(&screens[i]);
+    }
 }
 
 EWMHWindowType
 ewmh_get_window_type(Window w) {
-       Atom rt;
-       Atom *type;
-       int fmt;
-       unsigned long n;
-       unsigned long extra;
-       int i;
-       EWMHWindowType ret;
-
-       i = XGetWindowProperty(dpy, w,
-               ewmh_atom[_NET_WM_WINDOW_TYPE],
-               0, 100, False, XA_ATOM, &rt, &fmt, &n, &extra,
-               (unsigned char **)&type);
-       if (i != Success || type == NULL)
-               return WTypeNone;
-       ret = WTypeNone;
-       for (; n; n--) {
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_DESKTOP]) {
-                       ret = WTypeDesktop;
-                       break;
-               }
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_DOCK]) {
-                       ret = WTypeDock;
-                       break;
-               }
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_TOOLBAR]) {
-                       ret = WTypeToolbar;
-                       break;
-               }
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_MENU]) {
-                       ret = WTypeMenu;
-                       break;
-               }
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_UTILITY]) {
-                       ret = WTypeUtility;
-                       break;
-               }
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_SPLASH]) {
-                       ret = WTypeSplash;
-                       break;
-               }
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_DIALOG]) {
-                       ret = WTypeDialog;
-                       break;
-               }
-               if (type[n - 1] ==
-                       ewmh_atom[_NET_WM_WINDOW_TYPE_NORMAL]) {
-                       ret = WTypeNormal;
-                       break;
-               }
-       }
-       XFree(type);
-       return ret;
+    Atom rt;
+    Atom *type;
+    int fmt;
+    unsigned long n;
+    unsigned long extra;
+    int i;
+    EWMHWindowType ret;
+
+    i = XGetWindowProperty(dpy, w,
+        ewmh_atom[_NET_WM_WINDOW_TYPE],
+        0, 100, False, XA_ATOM, &rt, &fmt, &n, &extra,
+        (unsigned char **)&type);
+    if (i != Success || type == NULL)
+        return WTypeNone;
+    ret = WTypeNone;
+    for (; n; n--) {
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_DESKTOP]) {
+            ret = WTypeDesktop;
+            break;
+        }
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_DOCK]) {
+            ret = WTypeDock;
+            break;
+        }
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_TOOLBAR]) {
+            ret = WTypeToolbar;
+            break;
+        }
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_MENU]) {
+            ret = WTypeMenu;
+            break;
+        }
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_UTILITY]) {
+            ret = WTypeUtility;
+            break;
+        }
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_SPLASH]) {
+            ret = WTypeSplash;
+            break;
+        }
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_DIALOG]) {
+            ret = WTypeDialog;
+            break;
+        }
+        if (type[n - 1] ==
+            ewmh_atom[_NET_WM_WINDOW_TYPE_NORMAL]) {
+            ret = WTypeNormal;
+            break;
+        }
+    }
+    XFree(type);
+    return ret;
 }
 
 
 Bool ewmh_get_window_name(Client *c) {
-#ifdef X_HAVE_UTF8_STRING
-       Atom rt;
-       char *name;
-       int fmt;
-       unsigned long n;
-       unsigned long extra;
-       int i;
-
-       i = XGetWindowProperty(dpy, c->window,
-               ewmh_atom[_NET_WM_NAME],
-               0, 100, False, utf8_string, &rt, &fmt, &n, &extra,
-               (unsigned char **)&name);
-       if (i != Success || name == NULL)
-               return False;
-       Client_Name(c, name, True);
-       XFree(name);
-       return True;
-#else
-       return False;
-#endif
+    Atom rt;
+    char *name;
+    int fmt;
+    unsigned long n;
+    unsigned long extra;
+    int i;
+
+    i = XGetWindowProperty(dpy, c->window,
+        ewmh_atom[_NET_WM_NAME],
+        0, 100, False, utf8_string, &rt, &fmt, &n, &extra,
+        (unsigned char **)&name);
+    if (i != Success || name == NULL)
+        return False;
+    Client_Name(c, name);
+    XFree(name);
+    return True;
 }
 
 Bool
 ewmh_hasframe(Client *c) {
-       switch (c->wtype) {
-       case WTypeDesktop:
-       case WTypeDock:
-       case WTypeMenu:
-       case WTypeSplash:
-               return False;
-       default:
-               return True;
-       }
-}
-
-void
-ewmh_get_state(Client *c) {
-       Atom rt;
-       Atom *state;
-       int fmt;
-       unsigned long n;
-       unsigned long extra;
-       int i;
-
-       if (c == NULL) return;
-       i = XGetWindowProperty(dpy, c->window,
-               ewmh_atom[_NET_WM_STATE],
-               0, 100, False, XA_ATOM, &rt, &fmt, &n, &extra,
-               (unsigned char **)&state);
-       if (i != Success || state == NULL) return;
-       c->wstate.skip_taskbar = False;
-       c->wstate.skip_pager = False;
-       c->wstate.fullscreen = False;
-       c->wstate.above = False;
-       c->wstate.below = False;
-       for (; n; n--) {
-               if (state[n - 1] ==
-                       ewmh_atom[_NET_WM_STATE_SKIP_TASKBAR])
-                       c->wstate.skip_taskbar = True;
-               if (state[n - 1] ==
-                       ewmh_atom[_NET_WM_STATE_SKIP_PAGER])
-                       c->wstate.skip_pager = True;
-               if (state[n - 1] ==
-                       ewmh_atom[_NET_WM_STATE_FULLSCREEN])
-                       c->wstate.fullscreen = True;
-               if (state[n - 1] ==
-                       ewmh_atom[_NET_WM_STATE_ABOVE])
-                       c->wstate.above = True;
-               if (state[n - 1] ==
-                       ewmh_atom[_NET_WM_STATE_BELOW])
-                       c->wstate.below = True;
-       }
-       XFree(state);
+    switch (c->wtype) {
+    case WTypeDesktop:
+    case WTypeDock:
+    case WTypeMenu:
+    case WTypeSplash:
+        return False;
+    default:
+        return True;
+    }
 }
 
 static Bool
 new_state(unsigned long action, Bool current)
 {
-       enum Action {remove, add, toggle};
-
-       switch (action) {
-       case remove:
-               return False;
-       case add:
-               return True;
-       case toggle:
-               if (current == True) return False; else return True;
-       }
-       fprintf(stderr,"%s: bad action in _NET_WM_STATE (%d)\n",
-               argv0, (int) action);
-       return current;
-}
-
-void
-ewmh_change_state(Client *c, unsigned long action,
-       unsigned long atom) {
-       Atom *a = (Atom *)&atom;
-       
-       if (atom == 0) return;
-       if (*a == ewmh_atom[_NET_WM_STATE_SKIP_TASKBAR])
-               c->wstate.skip_taskbar =
-                       new_state(action, c->wstate.skip_taskbar);
-       if (*a == ewmh_atom[_NET_WM_STATE_SKIP_PAGER])
-               c->wstate.skip_pager =
-                       new_state(action, c->wstate.skip_pager);
-       if (*a == ewmh_atom[_NET_WM_STATE_FULLSCREEN]) {
-               Bool was_fullscreen = c->wstate.fullscreen;
-
-               c->wstate.fullscreen =
-                       new_state(action, c->wstate.fullscreen);
-               if (was_fullscreen == False &&
-                       c->wstate.fullscreen == True) Client_EnterFullScreen(c);
-               if (was_fullscreen == True &&
-                       c->wstate.fullscreen == False) Client_ExitFullScreen(c);
-       }
-       if (*a == ewmh_atom[_NET_WM_STATE_ABOVE])
-               c->wstate.above =
-                       new_state(action, c->wstate.above);
-       if (*a == ewmh_atom[_NET_WM_STATE_BELOW])
-               c->wstate.below =
-                       new_state(action, c->wstate.below);
-       ewmh_set_state(c);
-
-       /* may have to shuffle windows in the stack after a change of state */
-       ewmh_set_client_list(c->screen);
-}
-
-void
-ewmh_set_state(Client *c) {
-       int atoms = 0;
-       Atom *a = NULL;
-       int i = 0;
-
-       if (c == NULL) return;
-
-       if (c->state != WithdrawnState) {
-               if (c->hidden == True) atoms++;
-               if (c->wstate.skip_taskbar == True) atoms++;
-               if (c->wstate.skip_pager == True) atoms++;
-               if (c->wstate.fullscreen == True) atoms++;
-               if (c->wstate.above == True) atoms++;
-               if (c->wstate.below == True) atoms++;
-               if (atoms > 0) a = malloc(sizeof(Atom) * atoms);
-
-               if (c->hidden == True) {
-                       a[i] = ewmh_atom[_NET_WM_STATE_HIDDEN];
-                       i++;
-               }
-               if (c->wstate.skip_taskbar == True) {
-                       a[i] = ewmh_atom[_NET_WM_STATE_SKIP_TASKBAR];
-                       i++;
-               }
-               if (c->wstate.skip_pager == True) {
-                       a[i] = ewmh_atom[_NET_WM_STATE_SKIP_PAGER];
-                       i++;
-               }
-               if (c->wstate.fullscreen == True) {
-                       a[i] = ewmh_atom[_NET_WM_STATE_FULLSCREEN];
-                       i++;
-               }
-               if (c->wstate.above == True) {
-                       a[i] = ewmh_atom[_NET_WM_STATE_ABOVE];
-                       i++;
-               }
-               if (c->wstate.below == True) {
-                       a[i] = ewmh_atom[_NET_WM_STATE_BELOW];
-                       i++;
-               }
-       }
-
-       XChangeProperty(dpy, c->window, ewmh_atom[_NET_WM_STATE],
-               XA_ATOM, 32, PropModeReplace, (unsigned char *)a, atoms);
-       if (a != NULL) free(a);
-       
+    enum Action {remove, add, toggle};
+
+    switch (action) {
+    case remove:
+        return False;
+    case add:
+        return True;
+    case toggle:
+        if (current == True) return False; else return True;
+    }
+    fprintf(stderr,"%s: bad action in _NET_WM_STATE (%d)\n",
+        argv0, (int) action);
+    return current;
 }
 
 void
@@ -412,166 +284,21 @@ ewmh_set_allowed(Client *c)
 /* FIXME: this is dumb - the allowed actions should be calculuated
  * but for now, anything goes.
  */
-       Atom action[4];
-
-       action[0] = ewmh_atom[_NET_WM_ACTION_MOVE];
-       action[1] = ewmh_atom[_NET_WM_ACTION_RESIZE];
-       action[2] = ewmh_atom[_NET_WM_ACTION_FULLSCREEN];
-       action[3] = ewmh_atom[_NET_WM_ACTION_CLOSE];
-       XChangeProperty(dpy, c->window, ewmh_atom[_NET_WM_ALLOWED_ACTIONS],
-               XA_ATOM, 32, PropModeReplace, (unsigned char *)action, 4);
-}
-
-void
-ewmh_set_strut(ScreenInfo *screen) {
-       Client *c;
-       EWMHStrut strut;
-       unsigned long data[4];
-       /* FIXME: add parameter to MakeSane rather than this hack */
-       Edge backup;
-
-       /* find largest reserved areas */
-       strut.left = 0;
-       strut.right = 0;
-       strut.top = 0;
-       strut.bottom = 0;
-       for (c = client_head(); c; c = c->next) {
-               if (c->screen != screen) continue;
-               if (c->strut.left > strut.left) strut.left = c->strut.left;
-               if (c->strut.right > strut.right) strut.right = c->strut.right;
-               if (c->strut.top > strut.top) strut.top = c->strut.top;
-               if (c->strut.bottom > strut.bottom)
-                       strut.bottom = c->strut.bottom;
-       }
-
-       /* if the reservered aread have not changed then we're done */
-       if ( screen->strut.left == strut.left &&
-               screen->strut.right == strut.right &&
-               screen->strut.top == strut.top &&
-               screen->strut.bottom == strut.bottom) return;
-
-       /* apply the new strut */
-       screen->strut.left = strut.left;
-       screen->strut.right = strut.right;
-       screen->strut.top = strut.top;
-       screen->strut.bottom = strut.bottom;
-
-       /* set the new workarea */
-       data[0] = strut.left;
-       data[1] = strut.top;
-       data[2] = screen->display_width - (strut.left + strut.right);
-       data[3] = screen->display_height - (strut.top + strut.bottom);
-       XChangeProperty(dpy, screen->root,
-               ewmh_atom[_NET_WORKAREA],
-               XA_CARDINAL, 32, PropModeReplace,
-               (unsigned char*)data, 4);
-
-       /* ensure no window fully occupy reserved areas */
-       for (c = client_head(); c; c = c->next) {
-               int x = c->size.x;
-               int y = c->size.y;
-
-               if (c->wstate.fullscreen == True) continue;
-               backup = interacting_edge;
-               interacting_edge = ENone;
-               Client_MakeSane(c, ENone, &x, &y, 0, 0);
-               interacting_edge = backup;
-               if (c->framed == True) {
-                       XMoveWindow(dpy, c->parent,
-                               c->size.x,
-                               c->size.y - titleHeight());
-               } else {
-                       XMoveWindow(dpy, c->parent,
-                               c->size.x, c->size.y);
-               }
-               sendConfigureNotify(c);
-       }
-       
-}
-
-/*
- * get _NET_WM_STRUT and if it is available recalulate the screens
- * reserved areas. the EWMH spec isn't clear about what we should do
- * about hidden windows. It seems silly to reserve space for an invisible
- * window, but the spec allows it. Ho Hum...           jfc
- */
-void
-ewmh_get_strut(Client *c) {
-       Atom rt;
-       unsigned long *strut;
-       int fmt;
-       unsigned long n;
-       unsigned long extra;
-       int i;
-
-       if (c == NULL) return;
-       i = XGetWindowProperty(dpy, c->window,
-               ewmh_atom[_NET_WM_STRUT],
-               0, 5, False, XA_CARDINAL, &rt, &fmt, &n, &extra,
-               (unsigned char **)&strut);
-       if (i != Success || strut == NULL || n < 4) return;
-       c->strut.left = (unsigned int) strut[0];
-       c->strut.right = (unsigned int) strut[1];
-       c->strut.top = (unsigned int) strut[2];
-       c->strut.bottom = (unsigned int) strut[3];
-       ewmh_set_strut(c->screen);
-}
-
-/* fix stack forces each window on the screen to be in the right place in
- * the window stack as indicated in the EWMH spec version 1.2 (section 7.10).
- */
-static void
-fix_stack(ScreenInfo *screen) {
-       Client *c;
-
-       /* this is pretty dumb. we should query the tree and only move
-        * those windows that require it. doing it regardless liek this
-        * causes the desktop to flicker
-        */
-
-       /* first lower clients with _NET_WM_STATE_BELOW */
-       for (c = client_head(); c; c = c->next) {
-               if (c->wstate.below == False) continue;
-               Client_Lower(c);
-       }
-
-       /* lower desktops - they are always the lowest */
-       for (c = client_head(); c; c = c->next) {
-               if (c->wtype != WTypeDesktop) continue;
-               Client_Lower(c);
-               break; /* only one desktop, surely */
-       }
-
-       /* raise clients with _NET_WM_STATE_ABOVE and docks
-        * (unless marked with _NET_WM_STATE_BELOW)
-        */
-       for (c = client_head(); c; c = c->next) {
-               if (!(c->wstate.above == True ||
-                       (c->wtype == WTypeDock &&
-                       c->wstate.below == False)))
-                       continue;
-               Client_Raise(c);
-       }
-
-       /* raise fullscreens - they're always on top */
-       /* Misam Saki reports problems with this and believes fullscreens
-        * should not be automatically raised.
-        *
-        * However if the code below is removed then the panel is raised above
-        * fullscreens, which is not desirable.
-        */
-       for (c = client_head(); c; c = c->next) {
-               if (c->wstate.fullscreen == False) continue;
-               Client_Raise(c);
-       }
+    Atom action[4];
+
+    action[0] = ewmh_atom[_NET_WM_ACTION_MOVE];
+    action[1] = ewmh_atom[_NET_WM_ACTION_RESIZE];
+    action[2] = ewmh_atom[_NET_WM_ACTION_FULLSCREEN];
+    action[3] = ewmh_atom[_NET_WM_ACTION_CLOSE];
+    XChangeProperty(dpy, c->window, ewmh_atom[_NET_WM_ALLOWED_ACTIONS],
+        XA_ATOM, 32, PropModeReplace, (unsigned char *)action, 4);
 }
 
-
 static Bool
 valid_for_client_list(ScreenInfo *screen, Client *c) {
-       if (c->screen != screen) return False;
-       if (c->state == WithdrawnState) return False;
-       return True;
+    if (c->screen != screen) return False;
+    if (c->state == WithdrawnState) return False;
+    return True;
 }
 
 /*
@@ -583,61 +310,60 @@ valid_for_client_list(ScreenInfo *screen, Client *c) {
 */
 void
 ewmh_set_client_list(ScreenInfo *screen) {
-       int no_clients=0;
-       Window *client_list=NULL;
-       Window *stacked_client_list=NULL;
-       Client *c;
-
-       if (screen == NULL || screen->ewmh_set_client_list == True) return;
-       screen->ewmh_set_client_list = True;
-       fix_stack(screen);
-       for (c = client_head(); c; c = c->next) {
-               if (valid_for_client_list(screen, c) == True) no_clients++;
-       }
-       if (no_clients > 0) {
-               int i;
-               Window dw1;
-               Window dw2;
-               Window *wins;
-               unsigned int win;
-               unsigned int nwins;
-
-               client_list = malloc(sizeof(Window) * no_clients);
-               i = no_clients - 1; /* array starts with oldest */
-               for (c = client_head(); c; c = c->next) {
-                       if (valid_for_client_list(screen, c) == True) {
-                               client_list[i] = c->window;
-                               i--;
-                               if (i < 0) break;
-                       }
-               }
-
-               stacked_client_list = malloc(sizeof(Window) * no_clients);
-               i = 0;
-               XQueryTree(dpy, screen->root, &dw1, &dw2, &wins, &nwins);
-               for (win = 0; win < nwins; win++) {
-                       c = Client_Get(wins[win]);
-                       if (!c) continue;
-                       if (valid_for_client_list(screen, c) == True) {
-                               stacked_client_list[i] = c->window;
-                               i++;
-                               if (i >= no_clients) break;
-                       }
-               }
-               if ( nwins > 0 ) XFree(wins);
-
-       }
-       XChangeProperty(dpy, screen->root,
-               ewmh_atom[_NET_CLIENT_LIST],
-               XA_WINDOW, 32, PropModeReplace,
-               (unsigned char*)client_list, no_clients);
-       XChangeProperty(dpy, screen->root,
-               ewmh_atom[_NET_CLIENT_LIST_STACKING],
-               XA_WINDOW, 32, PropModeReplace,
-               (unsigned char*)stacked_client_list, no_clients);
-       if (no_clients > 0 ) {
-               free(client_list);
-               free(stacked_client_list);
-       }
-       screen->ewmh_set_client_list = False;
+    int no_clients=0;
+    Window *client_list=NULL;
+    Window *stacked_client_list=NULL;
+    Client *c;
+
+    if (screen == NULL || screen->ewmh_set_client_list == True) return;
+    screen->ewmh_set_client_list = True;
+    for (c = Client_List(); c; c = c->next) {
+        if (valid_for_client_list(screen, c) == True) no_clients++;
+    }
+    if (no_clients > 0) {
+        int i;
+        Window dw1;
+        Window dw2;
+        Window *wins;
+        unsigned int win;
+        unsigned int nwins;
+
+        client_list = malloc(sizeof(Window) * no_clients);
+        i = no_clients - 1; /* array starts with oldest */
+        for (c = Client_List(); c; c = c->next) {
+            if (valid_for_client_list(screen, c) == True) {
+                client_list[i] = c->window;
+                i--;
+                if (i < 0) break;
+            }
+        }
+
+        stacked_client_list = malloc(sizeof(Window) * no_clients);
+        i = 0;
+        XQueryTree(dpy, screen->root, &dw1, &dw2, &wins, &nwins);
+        for (win = 0; win < nwins; win++) {
+            c = Client_Get(wins[win]);
+            if (!c) continue;
+            if (valid_for_client_list(screen, c) == True) {
+                stacked_client_list[i] = c->window;
+                i++;
+                if (i >= no_clients) break;
+            }
+        }
+        if ( nwins > 0 ) XFree(wins);
+
+    }
+    XChangeProperty(dpy, screen->root,
+        ewmh_atom[_NET_CLIENT_LIST],
+        XA_WINDOW, 32, PropModeReplace,
+        (unsigned char*)client_list, no_clients);
+    XChangeProperty(dpy, screen->root,
+        ewmh_atom[_NET_CLIENT_LIST_STACKING],
+        XA_WINDOW, 32, PropModeReplace,
+        (unsigned char*)stacked_client_list, no_clients);
+    if (no_clients > 0 ) {
+        free(client_list);
+        free(stacked_client_list);
+    }
+    screen->ewmh_set_client_list = False;
 }
diff --git a/lwm b/lwm
index 12e9c0380f915c58d5402f2e2527a42ed46ad6ea..d0ecf68d598e589a12bc46b677fa1e993a4febb2 100755 (executable)
Binary files a/lwm and b/lwm differ
diff --git a/lwm.c b/lwm.c
index 662dfcd2fb9ee633a551767e56d9f5558650bb2c..64359ecd5983c5531dd369527abd937c0755aa78 100644 (file)
--- a/lwm.c
+++ b/lwm.c
 
 #include "lwm.h"
 
-Mode mode;                     /* The window manager's mode. (See "lwm.h".) */
-int start_x;                   /* The X position where the mode changed. */
-int start_y;                   /* The Y position where the mode changed. */
-
-Display * dpy;                 /* The connection to the X server. */
-int screen_count;              /* The number of screens. */
-ScreenInfo * screens;          /* Information about these screens. */
+char    *font_name = DEFAULT_TITLE_FONT;        /* User's choice of titlebar font. */
+int border = DEFAULT_BORDER;            /* User's choice of border size. */
+Mode mode;          /* The window manager's mode. (See "lwm.h".) */
+int start_x;            /* The X position where the mode changed. */
+int start_y;            /* The Y position where the mode changed. */
+
+Display * dpy;          /* The connection to the X server. */
+int screen_count;       /* The number of screens. */
+ScreenInfo * screens;       /* Information about these screens. */
 ScreenInfo * current_screen;
 
-XFontSet font_set = NULL;      /* Font set for title var */
+XFontSet font_set = NULL;   /* Font set for title var */
 XFontSetExtents *font_set_ext = NULL;
-XFontSet popup_font_set = NULL;        /* Font set for popups */
-XFontSetExtents *popup_font_set_ext = NULL;
-
-Bool shape;                    /* Does server have Shape Window extension? */
-int shape_event;               /* ShapeEvent event type. */
 
 /* Atoms we're interested in. See the ICCCM for more information. */
 Atom wm_state;
@@ -62,422 +59,235 @@ Atom wm_take_focus;
 Atom wm_colormaps;
 Atom compound_text;
 
-/** Netscape uses this to give information about the URL it's displaying. */
-Atom _mozilla_url;
-
-/*
- * if we're really short of a clue we might look at motif hints, and
- * we're not going to link with motif, so we'll have to do it by hand
- */
-Atom motif_wm_hints;
-
 char *argv0;
 
 static void initScreens(void);
 static void initScreen(int);
 
-char   *font_name;             /* User's choice of titlebar font. */
-char   *popup_font_name;       /* User's choice of menu font. */
-char   *btn1_command;          /* User's choice of button 1 command. */
-char   *btn2_command;          /* User's choice of button 2 command. */
-int    border;                 /* User's choice of border size. */
-FocusMode focus_mode;          /* User's choice of focus mode (default enter) */
-
-void getMousePosition(int * x, int * y) {
-       Window root, child;
-       int t1, t2;
-       unsigned int b;
-
-       /* It doesn't matter which root window we give this call. */
-       XQueryPointer(dpy, screens[0].root, &root, &child, x, y, &t1, &t2, &b);
-       current_screen = getScreenFromRoot(root);
-}
-
-void parseResources(void) {
-       /* Set our fall-back defaults. */
-       font_name = DEFAULT_TITLE_FONT;
-       popup_font_name = DEFAULT_POPUP_FONT;
-       border = DEFAULT_BORDER;
-       btn1_command = 0;
-       btn2_command = DEFAULT_TERMINAL;
-       focus_mode = focus_enter;
-}
-
-int main(int argc, char *argv[]) {
-       XEvent ev;
-       struct sigaction sa;
-       int dpy_fd, max_fd;
-
-       argv0 = argv[0];
-
-       mode = wm_initialising;
-
-       /* Open a connection to the X server. */
-       dpy = XOpenDisplay(NULL);
-       if (dpy == 0)
-               panic("can't open display.");
-
-       parseResources();
-
-       /* Set up an error handler. */
-       XSetErrorHandler(errorHandler);
-
-       /* Set up signal handlers. */
-       signal(SIGTERM, Terminate);
-       signal(SIGINT, Terminate);
-       signal(SIGHUP, Terminate);
-
-       /* Ignore SIGCHLD. */
-       sa.sa_handler = SIG_IGN;
-#ifdef SA_NOCLDWAIT
-       sa.sa_flags = SA_NOCLDWAIT;
-#else
-       sa.sa_flags = 0;
-#endif
-       sigemptyset(&sa.sa_mask);
-       sigaction(SIGCHLD, &sa, 0);
-
-       /* Internalize useful atoms. */
-       wm_state = XInternAtom(dpy, "WM_STATE", False);
-       wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False);
-       wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
-       wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
-       wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
-       wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
-       compound_text = XInternAtom(dpy, "COMPOUND_TEXT", False);
-
-       _mozilla_url = XInternAtom(dpy, "_MOZILLA_URL", False);
-
-       motif_wm_hints = XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
-
-       ewmh_init();
-
-       /*
-        * Get fonts for our titlebar and our popup window. We try to
-        * get Lucida, but if we can't we make do with fixed because everyone
-        * has that.
-        */
-       {
-               /* FIXME: do these need to be freed? */
-               char **missing;
-               char *def;
-               int missing_count;
-
-               font_set = XCreateFontSet(dpy, font_name,
-                       &missing, &missing_count, &def);
-               if (font_set == NULL)
-                       font_set = XCreateFontSet(dpy, "fixed",
-                               &missing, &missing_count, &def);
-               if (font_set == NULL)
-                       panic("unable to create font set for title font");
-               if (missing_count > 0)
-                       fprintf(stderr,"%s: warning: missing %d charset"
-                               "%s for title font\n", argv0, missing_count,
-                               (missing_count == 1)?"":"s");
-               font_set_ext = XExtentsOfFontSet(font_set);
-
-               popup_font_set = XCreateFontSet(dpy, popup_font_name,
-                       &missing, &missing_count, &def);
-               if (popup_font_set == NULL)
-                       popup_font_set = XCreateFontSet(dpy, "fixed",
-                               &missing, &missing_count, &def);
-               if (popup_font_set == NULL)
-                       panic("unable to create font set for popup font");
-               if (missing_count > 0)
-                       fprintf(stderr,"%s: warning: missing %d charset"
-                               "%s for popup font\n", argv0, missing_count,
-                               (missing_count == 1)?"":"s");
-               popup_font_set_ext = XExtentsOfFontSet(popup_font_set);
-       }
-
-       initScreens();
-       ewmh_init_screens();
-
-       /* See if the server has the Shape Window extension. */
-       shape = serverSupportsShapes();
-
-       /*
-        * Initialisation is finished, but we start off not interacting with the
-        * user.
-        */
-       mode = wm_idle;
-
-       /*
-        * The main event loop.
-        */
-       dpy_fd = ConnectionNumber(dpy);
-       max_fd = dpy_fd + 1;
-       for (;;) {
-               fd_set readfds;
-
-               FD_ZERO(&readfds);
-               FD_SET(dpy_fd, &readfds);
-               if (select(max_fd, &readfds, NULL, NULL, NULL) > -1) {
-                   if (FD_ISSET(dpy_fd, &readfds)) {
-                           while (XPending(dpy)) {
-                               XNextEvent(dpy, &ev);
-                               dispatch(&ev);
-                           }
-                   }
-               }
-       }
+/*ARGSUSED*/
+extern int
+main(int argc, char *argv[]) {
+    XEvent ev;
+    argv0 = argv[0];
+    mode = wm_initialising;
+
+    /* Open a connection to the X server. */
+    dpy = XOpenDisplay(NULL);
+    if (dpy == 0)
+        panic("can't open display.");
+
+    /* Set up an error handler. */
+    XSetErrorHandler(errorHandler);
+
+    /* Internalize useful atoms. */
+    wm_state = XInternAtom(dpy, "WM_STATE", False);
+    wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False);
+    wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
+    wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+    wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
+    wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
+    compound_text = XInternAtom(dpy, "COMPOUND_TEXT", False);
+    ewmh_init();
+
+    /*
+     * Get fonts for our titlebar and our popup window. We try to
+     * get Lucida, but if we can't we make do with fixed because everyone
+     * has that.
+     */
+    {
+        /* FIXME: do these need to be freed? */
+        char **missing;
+        char *def;
+        int missing_count;
+
+        font_set = XCreateFontSet(dpy, font_name,
+            &missing, &missing_count, &def);
+        if (font_set == NULL)
+            font_set = XCreateFontSet(dpy, "fixed",
+                &missing, &missing_count, &def);
+        if (font_set == NULL)
+            panic("unable to create font set for title font");
+        if (missing_count > 0)
+            fprintf(stderr,"%s: warning: missing %d charset"
+                "%s for title font\n", argv0, missing_count,
+                (missing_count == 1)?"":"s");
+        font_set_ext = XExtentsOfFontSet(font_set);
+    }
+
+    initScreens();
+    ewmh_init_screens();
+
+    /*
+     * Initialisation is finished, but we start off not interacting with the
+     * user.
+     */
+    mode = wm_idle;
+
+    /*
+     * The main event loop.
+     */
+    for (;;)
+    {
+        XNextEvent(dpy, &ev);
+        dispatch(&ev);
+    }
 }
 
 void
 sendConfigureNotify(Client *c) {
-       XConfigureEvent ce;
-
-       ce.type = ConfigureNotify;
-       ce.event = c->window;
-       ce.window = c->window;
-       if (c->framed == True) {
-               ce.x = c->size.x + border;
-               ce.y = c->size.y + border;
-               ce.width = c->size.width - 2 * border;
-               ce.height = c->size.height - 2 * border;
-               ce.border_width = c->border;
-       } else {
-               ce.x = c->size.x;
-               ce.y = c->size.y;
-               ce.width = c->size.width;
-               ce.height = c->size.height;
-               ce.border_width = c->border;
-       }
-       ce.above = None;
-       ce.override_redirect = 0;
-       XSendEvent(dpy, c->window, False, StructureNotifyMask, (XEvent *) &ce);
+    XConfigureEvent ce;
+    ce.type = ConfigureNotify;
+    ce.event = c->window;
+    ce.window = c->window;
+    if (c->framed == True) {
+        ce.x = c->size.x + border;
+        ce.y = c->size.y + border;
+        ce.width = c->size.width - 2 * border;
+        ce.height = c->size.height - 2 * border;
+        ce.border_width = c->border;
+    } else {
+        ce.x = c->size.x;
+        ce.y = c->size.y;
+        ce.width = c->size.width;
+        ce.height = c->size.height;
+        ce.border_width = c->border;
+    }
+    ce.above = None;
+    ce.override_redirect = 0;
+    XSendEvent(dpy, c->window, False, StructureNotifyMask, (XEvent *) &ce);
 }
 
 extern void
 scanWindowTree(int screen) {
-       unsigned int i;
-       unsigned int nwins;
-       Client * c;
-       Window dw1;
-       Window dw2;
-       Window * wins;
-       XWindowAttributes attr;
-
-       XQueryTree(dpy, screens[screen].root, &dw1, &dw2, &wins, &nwins);
-       for (i = 0; i < nwins; i++) {
-               XGetWindowAttributes(dpy, wins[i], &attr);
-               if (attr.override_redirect /*|| isShaped(wins[i])*/ || wins[i] == screens[screen].popup)
-                       continue;
-               c = Client_Add(wins[i], screens[screen].root);
-               if (c != 0 && c->window == wins[i]) {
-                       c->screen = &screens[screen];
-                       c->size.x = attr.x;
-                       c->size.y = attr.y;
-/* we'll leave it until it's managed
-                       if (c->framed == True) {
-                               c->size.x -= border;
-                               c->size.y -= border;
-                       }
-*/
-                       c->size.width  = attr.width;
-                       c->size.height = attr.height;
-/* we'll leave it until it's managed
-                       if (c->framed == True) {
-                               c->size.width  += 2 * border;
-                               c->size.height += 2 * border;
-                       }
-*/
-                       c->border = attr.border_width;
-                       if (attr.map_state == IsViewable) {
-                               c->internal_state = IPendingReparenting;
-                               manage(c, 1);
-                       }
-               }
-       }
-       XFree(wins);
-}
-
-/*ARGSUSED*/
-extern void
-shell(ScreenInfo * screen, int button, int x, int y) {
-       char * command = NULL;
-       char * sh;
-
-       /* Get the command we're to execute. Give up if there isn't one. */
-       if (button == Button1)
-               command = btn1_command;
-       if (button == Button2)
-               command = btn2_command;
-       if (command == NULL)
-               return;
-
-       sh = getenv("SHELL");
-       if (sh == 0)
-               sh = "/bin/sh";
-
-       switch (fork()) {
-       case 0:         /* Child. */
-               close(ConnectionNumber(dpy));
-               if (screen && screen->display_spec != 0)
-                       putenv(screen->display_spec);
-               execl(sh, sh, "-c", command, NULL);
-               fprintf(stderr, "%s: can't exec \"%s -c %s\"\n", argv0, sh,
-                       command);
-               execlp("xterm", "xterm", NULL);
-               exit(EXIT_FAILURE);
-       case -1:        /* Error. */
-               fprintf(stderr, "%s: couldn't fork\n", argv0);
-               break;
-       }
+    unsigned int i;
+    unsigned int nwins;
+    Client * c;
+    Window dw1;
+    Window dw2;
+    Window * wins;
+    XWindowAttributes attr;
+
+    XQueryTree(dpy, screens[screen].root, &dw1, &dw2, &wins, &nwins);
+    for (i = 0; i < nwins; i++) {
+        XGetWindowAttributes(dpy, wins[i], &attr);
+        if (attr.override_redirect)
+            continue;
+        c = Client_Add(wins[i], screens[screen].root);
+        if (c != 0 && c->window == wins[i]) {
+            c->screen = &screens[screen];
+            c->size.x = attr.x;
+            c->size.y = attr.y;
+            c->size.width  = attr.width;
+            c->size.height = attr.height;
+            c->border = attr.border_width;
+            if (attr.map_state == IsViewable) {
+                c->internal_state = IPendingReparenting;
+                manage(c, 1);
+            }
+        }
+    }
+    XFree(wins);
 }
 
 extern int
 titleHeight(void) {
-       return font_set_ext->max_logical_extent.height;
+    return font_set_ext->max_logical_extent.height;
 }
 
 extern int
 ascent(XFontSetExtents *font_set_ext) {
-       return abs(font_set_ext->max_logical_extent.y);
-}
-
-extern int
-popupHeight(void) {
-       return popup_font_set_ext->max_logical_extent.height;
+    return abs(font_set_ext->max_logical_extent.y);
 }
 
 extern int
 titleWidth(XFontSet font_set, Client *c) {
-       XRectangle ink;
-       XRectangle logical;
-       char *name;
-       int namelen;
-
-       if (c == NULL) return 0;
-       if (c->menu_name == NULL) {
-               name = c->name;
-               namelen = c->namelen;
-       } else {
-               name = c->menu_name;
-               namelen = c->menu_namelen;
-       }
-       if (name == NULL) return 0;
-#ifdef X_HAVE_UTF8_STRING
-       if (c->name_utf8 == True)
-               Xutf8TextExtents(font_set, name, namelen,
-                       &ink, &logical);
-       else
-#endif
-               XmbTextExtents(font_set, name, namelen,
-                       &ink, &logical);
-
-       return logical.width;
-}
-
-extern int
-popupWidth(char *string, int string_length) {
-       XRectangle ink;
-       XRectangle logical;
-
-       XmbTextExtents(popup_font_set, string, string_length,
-               &ink, &logical);
-
-       return logical.width;
+    XRectangle ink;
+    XRectangle logical;
+    char *name;
+    int namelen;
+
+    if (c == NULL) return 0;
+    name = c->name;
+    namelen = c->namelen;
+    if (name == NULL) return 0;
+    Xutf8TextExtents(font_set, name, namelen,
+        &ink, &logical);
+
+    return logical.width;
 }
 
 static void
 initScreens(void) {
-       int screen;
-
-       /* Find out how many screens we've got, and allocate space for their info. */
-       screen_count = ScreenCount(dpy);
-       screens = (ScreenInfo *) malloc(screen_count * sizeof(ScreenInfo));
-
-       /* Go through the screens one-by-one, initialising them. */
-       for (screen = 0; screen < screen_count; screen++) {
-               initialiseCursors(screen);
-               initScreen(screen);
-               scanWindowTree(screen);
-       }
+    int screen;
+
+    /* Find out how many screens we've got, and allocate space for their info. */
+    screen_count = ScreenCount(dpy);
+    screens = (ScreenInfo *) malloc(screen_count * sizeof(ScreenInfo));
+
+    /* Go through the screens one-by-one, initialising them. */
+    for (screen = 0; screen < screen_count; screen++) {
+        initialiseCursors(screen);
+        initScreen(screen);
+        scanWindowTree(screen);
+    }
 }
 
 static void
 initScreen(int screen) {
-       XGCValues gv;
-       XSetWindowAttributes attr;
-       XColor colour, exact;
-       int len;
-       char * display_string = DisplayString(dpy);
-       char * colon = strrchr(display_string, ':');
-       char * dot = NULL;
-
-       /* Set the DISPLAY specification. */
-       if (colon) {
-               dot = strrchr(colon, '.');
-               len = 9 + strlen(display_string) + ((dot == 0) ? 2 : 0) + 10;
-               screens[screen].display_spec = (char *) malloc(len);
-               sprintf(screens[screen].display_spec, "DISPLAY=%s", display_string);
-               if (dot == 0) dot = screens[screen].display_spec + len - 3;
-               else dot = strrchr(screens[screen].display_spec, '.');
-               sprintf(dot, ".%i", screen);
-       } else {
-               screens[screen].display_spec = 0;
-       }
-
-       /* Find the root window. */
-       screens[screen].root = RootWindow(dpy, screen);
-       screens[screen].display_width = DisplayWidth(dpy, screen);
-       screens[screen].display_height = DisplayHeight(dpy, screen);
-       screens[screen].strut.left = 0;
-       screens[screen].strut.right = 0;
-       screens[screen].strut.top = 0;
-       screens[screen].strut.bottom = 0;
-
-       /* Get the pixel values of the only two colours we use. */
-       screens[screen].black = BlackPixel(dpy, screen);
-       screens[screen].white = WhitePixel(dpy, screen);
-       XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "DimGray", &colour, &exact);
-       screens[screen].gray = colour.pixel;
-
-       /* Set up root (frame) GC's. */
-       gv.foreground = screens[screen].black ^ screens[screen].white;
-       gv.background = screens[screen].white;
-       gv.function = GXxor;
-       gv.line_width = 1;
-       gv.subwindow_mode = IncludeInferiors;
-       screens[screen].gc_thin = XCreateGC(dpy, screens[screen].root,
-               GCForeground | GCBackground | GCFunction |
-               GCLineWidth | GCSubwindowMode, &gv);
-
-       gv.line_width = 2;
-       screens[screen].gc = XCreateGC(dpy, screens[screen].root,
-               GCForeground | GCBackground | GCFunction |
-               GCLineWidth | GCSubwindowMode, &gv);
-
-       /* Create a window for our popup. */
-       screens[screen].popup = XCreateSimpleWindow(dpy, screens[screen].root,
-               0, 0, 1, 1, 1, screens[screen].black, screens[screen].white);
-       attr.event_mask = ButtonMask | ButtonMotionMask | ExposureMask;
-       XChangeWindowAttributes(dpy, screens[screen].popup, CWEventMask, &attr);
-
-       /* Create menu GC. */
-       gv.line_width = 1;
-       screens[screen].menu_gc = XCreateGC(dpy, screens[screen].popup,
-               GCForeground | GCBackground | GCFunction |
-               GCLineWidth | GCSubwindowMode, &gv);
-
-       /* Create size indicator GC. */
-       gv.foreground = screens[screen].black;
-       gv.function = GXcopy;
-       screens[screen].size_gc = XCreateGC(dpy, screens[screen].popup,
-               GCForeground | GCBackground | GCFunction |
-               GCLineWidth | GCSubwindowMode, &gv);
-
-       /* Announce our interest in the root window. */
-       attr.cursor = screens[screen].root_cursor;
-       attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
-               ColormapChangeMask | ButtonPressMask | PropertyChangeMask |
-               EnterWindowMask;
-       XChangeWindowAttributes(dpy, screens[screen].root, CWCursor |
-               CWEventMask, &attr);
-
-       /* Make sure all our communication to the server got through. */
-       XSync(dpy, False);
+    XGCValues gv;
+    XSetWindowAttributes attr;
+    XColor colour, exact;
+    int len;
+    char * display_string = DisplayString(dpy);
+    char * colon = strrchr(display_string, ':');
+    char * dot = NULL;
+
+    /* Set the DISPLAY specification. */
+    if (colon) {
+            dot = strrchr(colon, '.');
+        len = 9 + strlen(display_string) + ((dot == 0) ? 2 : 0) + 10;
+        screens[screen].display_spec = (char *) malloc(len);
+        sprintf(screens[screen].display_spec, "DISPLAY=%s", display_string);
+        if (dot == 0) dot = screens[screen].display_spec + len - 3;
+        else dot = strrchr(screens[screen].display_spec, '.');
+        sprintf(dot, ".%i", screen);
+    } else {
+        screens[screen].display_spec = 0;
+    }
+
+    /* Find the root window. */
+    screens[screen].root = RootWindow(dpy, screen);
+    screens[screen].display_width = DisplayWidth(dpy, screen);
+    screens[screen].display_height = DisplayHeight(dpy, screen);
+
+    /* Get the pixel values of the only two colours we use. */
+    screens[screen].black = BlackPixel(dpy, screen);
+    screens[screen].white = WhitePixel(dpy, screen);
+    XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "DimGray", &colour, &exact);
+    screens[screen].gray = colour.pixel;
+
+    /* Set up root (frame) GC's. */
+    gv.foreground = screens[screen].black ^ screens[screen].white;
+    gv.background = screens[screen].white;
+    gv.function = GXxor;
+    gv.line_width = 1;
+    gv.subwindow_mode = IncludeInferiors;
+
+    gv.line_width = 2;
+    screens[screen].gc = XCreateGC(dpy, screens[screen].root,
+        GCForeground | GCBackground | GCFunction |
+        GCLineWidth | GCSubwindowMode, &gv);
+
+    /* Announce our interest in the root window. */
+    attr.cursor = screens[screen].root_cursor;
+    attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
+        ColormapChangeMask | ButtonPressMask | PropertyChangeMask |
+        EnterWindowMask;
+    XChangeWindowAttributes(dpy, screens[screen].root, CWCursor |
+        CWEventMask, &attr);
+
+    /* Make sure all our communication to the server got through. */
+    XSync(dpy, False);
 }
 
 /**
@@ -485,11 +295,11 @@ Find the screen for which root is the root window.
 */
 ScreenInfo *
 getScreenFromRoot(Window root) {
-       int screen;
+    int screen;
 
-       for (screen = 0; screen < screen_count; screen++)
-               if (screens[screen].root == root)
-                       return &screens[screen];
+    for (screen = 0; screen < screen_count; screen++)
+        if (screens[screen].root == root)
+            return &screens[screen];
 
-       return 0;
+    return 0;
 }
diff --git a/lwm.h b/lwm.h
index 136350bc90c73742bfff493847a2463050359152..30de4e4a10ea9ab7e341d9b4394503e8f6ddf20f 100644 (file)
--- a/lwm.h
+++ b/lwm.h
 /* --- Administrator-configurable defaults. --- */
 
 #define DEFAULT_TITLE_FONT "-*-lucida-bold-r-normal-sans-14-*-*-*-p-*-iso10646-1"
-#define DEFAULT_POPUP_FONT "-*-lucida-medium-r-normal-sans-12-*-*-*-p-*-iso10646-1"
-#define DEFAULT_TERMINAL "xterm"
-#define DEFAULT_BORDER 6
-
-#define HIDE_BUTTON Button3
-#define MOVE_BUTTON Button2
-#define RESHAPE_BUTTON Button1
-
-#define EDGE_RESIST 32
+#define DEFAULT_TERMINAL   "xterm"
+#define DEFAULT_BORDER     3
 
 /* --- End of administrator-configurable defaults. --- */
 
  * initialising.
  */
 typedef enum {
-       wm_initialising,
-       wm_idle,
-       wm_reshaping,
-       wm_menu_up,
-       wm_closing_window,
-       wm_hiding_window
+    wm_initialising,
+    wm_idle,
+    wm_reshaping,
 } Mode;
 
 /** Window internal state. Yuck. */
 typedef enum {
-       IPendingReparenting, INormal
-} IState ;
-
-
-/**
-* Focus mode, may me (and defaults to) enter where entering a window gives
-* that window input focus, or click where a window must be explicitly clicked
-* to give it the focus.
-*/
-typedef enum {
-       focus_enter,    focus_click
-} FocusMode;
+    IPendingReparenting, INormal
+} IState;
 
 /**
 * Window edge, used in resizing. The `edge' ENone is used to signify a
@@ -74,20 +54,20 @@ typedef enum {
 * this isn't a special case to be treated separately.
 */
 typedef enum {
-       ETopLeft,       ETop,           ETopRight,
-       ERight,         ENone,          ELeft,
-       EBottomLeft,    EBottom,        EBottomRight,
-       E_LAST
+    ETopLeft,    ETop,    ETopRight,
+    ERight,      ENone,   ELeft,
+    EBottomLeft, EBottom, EBottomRight,
+    E_LAST
 } Edge ;
 
 /**
 * EWMH direction for _NET_WM_MOVERESIZE
 */
 typedef enum {
-       DSizeTopLeft,           DSizeTop,               DSizeTopRight,
-       DSizeRight,             DSizeBottomRight,       DSizeBottom,
-       DSizeBottomLeft,        DSizeLeft,              DMove,
-       DSizeKeyboard,          DMoveKeyboard
+    DSizeTopLeft,    DSizeTop,         DSizeTopRight,
+    DSizeRight,      DSizeBottomRight, DSizeBottom,
+    DSizeBottomLeft, DSizeLeft,        DMove,
+    DSizeKeyboard,   DMoveKeyboard
 } EWMHDirection;
 
 /**
@@ -96,119 +76,57 @@ typedef enum {
 * hints should be used instead.
 */
 typedef enum {
-       WTypeDesktop,   WTypeDock,      WTypeToolbar,
-       WTypeMenu,      WTypeUtility,   WTypeSplash,
-       WTypeDialog,    WTypeNormal,    WTypeNone
+    WTypeDesktop, WTypeDock,    WTypeToolbar,
+    WTypeMenu,    WTypeUtility, WTypeSplash,
+    WTypeDialog,  WTypeNormal,  WTypeNone
 } EWMHWindowType;
 
-/**
-* EWMH window state, See section 5.7 of the EWMH specification (1.2).
-* lwm does not support all states. _NET_WM_STATE_HIDDEN is taken from
-* Client.hidden.
-*/
-typedef struct {
-       Bool skip_taskbar;
-       Bool skip_pager;
-       Bool fullscreen;
-       Bool above;
-       Bool below;
-} EWMHWindowState;
-
-/**
-* EWMH "strut", or area on each edge of the screen reserved for docking
-* bars/panels.
-*/
-typedef struct {
-       unsigned int left;
-       unsigned int right;
-       unsigned int top;
-       unsigned int bottom;
-} EWMHStrut;
-
 /**
 * Screen information.
 */
 typedef struct ScreenInfo ScreenInfo;
 struct ScreenInfo {
-       Window root;
-       Window popup;
-       Window ewmh_compat;
-
-       int display_width;              /* The width of the screen. */
-       int display_height;             /* The height of the screen. */
-       EWMHStrut strut;                /* reserved areas */
-
-       GC gc;          /* The default GC. */
-       GC gc_thin;     /* The default GC but with thinner lines. */
-       GC menu_gc;     /* The GC for the popup window (menu). */
-       GC size_gc;     /* The GC for the popup window (sizing). */
-
-       unsigned long black;            /* Black pixel value. */
-       unsigned long white;    /* White pixel value. */
-       unsigned long gray;             /* Gray pixel value. */
-
-       Cursor root_cursor;
-       Cursor box_cursor;
-
-       Cursor cursor_map[E_LAST];
-
-       Bool ewmh_set_client_list;      /* hack to prevent recursion */
-
-       char * display_spec;
+    Window root;
+    Window ewmh_compat;
+    int display_width;   /* The width of the screen. */
+    int display_height;  /* The height of the screen. */
+    GC gc;               /* The default GC. */
+    unsigned long black; /* Black pixel value. */
+    unsigned long white; /* White pixel value. */
+    unsigned long gray;  /* Gray pixel value. */
+
+    Cursor root_cursor;
+    Cursor box_cursor;
+    Cursor cursor_map[E_LAST];
+    Bool ewmh_set_client_list;  /* hack to prevent recursion */
+    char * display_spec;
 };
 
-typedef struct Client Client;
-struct Client {
-       Window window;          /* Client's window. */
-       Window parent;          /* Window manager frame. */
-       Window trans;           /* Window that client is a transient for. */
-
-       Bool framed;            /* True is lwm is maintaining a frame */
-
-       Client * next;          /* Next window in client list. */
-
-       int border;             /* Client's original border width. */
-
-       XSizeHints size;        /* Client's current geometry information. */
-       XSizeHints return_size; /* Client's old geometry information. */
-       int state;              /* Window state. See ICCCM and <X11/Xutil.h> */
-
-       Bool hidden;            /* True if this client is hidden. */
-       IState internal_state;
-       int proto;
-
-       int accepts_focus;      /* Does this window want keyboard events? */
-
-       char * name;            /* Name used for title in frame. */
-       int namelen;
-       char * menu_name;       /* Name used in root popup */
-       int menu_namelen;
-       Bool name_utf8;
-
-       ScreenInfo * screen;
-
-       Edge cursor;            /* indicates which cursor is being used for parent window */
-
-       EWMHWindowType wtype;
-       EWMHWindowState wstate;
-       EWMHStrut strut;                /* reserved areas */
-
-       /* Colourmap scum. */
-       Colormap cmap;
-       int ncmapwins;
-       Window * cmapwins;
-       Colormap * wmcmaps;
-};
-
-
-/*
- *     c->proto is a bitarray of these
- */
+/* Client flags for EWMH protocols and window behavior */
 enum {
-       Pdelete = 1,
-       Ptakefocus = 2
+    F_ACCEPT_FOCUS    = (1 << 0),
+    F_EWMH_DELETE     = (1 << 1),
+    F_EWMH_TAKE_FOCUS = (1 << 2),
 };
 
+typedef struct Client {
+    strcut Client* next; /* Next window in client list. */
+    Window window;       /* Client's window. */
+    Window parent;       /* Window manager frame. */
+    Window trans;        /* Window that client is a transient for. */
+    Bool framed;         /* True is lwm is maintaining a frame */
+    int border;          /* Client's original border width. */
+    XSizeHints size;     /* Client's current geometry information. */
+    int state;           /* Window state. See ICCCM and <X11/Xutil.h> */
+    int flags;           /* Flags governing client behavior */
+    char * name;         /* Name used for title in frame. */
+    int namelen;         /* Length of client name */
+    Edge cursor;         /* indicates which cursor is being used for parent window */
+    IState internal_state;
+    ScreenInfo * screen;
+    EWMHWindowType wtype;
+} Client;
+
 /*
  * This should really have been in X.h --- if you select both ButtonPress
  * and ButtonRelease events, the server makes an automatic grab on the
@@ -216,7 +134,9 @@ enum {
  */
 #define ButtonMask (ButtonPressMask | ButtonReleaseMask)
 
-/*     lwm.c */
+/*  lwm.c */
+extern char *font_name;
+extern int border;
 extern Mode mode;
 extern int start_x;
 extern int start_y;
@@ -226,39 +146,29 @@ extern ScreenInfo * screens;
 extern ScreenInfo * current_screen;
 extern XFontSet font_set;
 extern XFontSetExtents *font_set_ext;
-extern XFontSet popup_font_set;
-extern XFontSetExtents *popup_font_set_ext;
-extern Atom _mozilla_url;
-extern Atom motif_wm_hints;
 extern Atom wm_state;
 extern Atom wm_change_state;
 extern Atom wm_protocols;
 extern Atom wm_delete;
 extern Atom wm_take_focus;
-extern Atom wm_colormaps;
 extern Atom compound_text;
-extern Bool shape;
-extern int shape_event;
 extern char *argv0;
-extern void shell(ScreenInfo *, int, int, int);
 extern void sendConfigureNotify(Client *);
 extern int titleHeight(void);
 extern int titleWidth(XFontSet font_set, Client *c);
-extern int popupHeight(void);
-extern int popupWidth(char *string, int string_length);
 extern int ascent(XFontSetExtents *font_set_ext);
 extern ScreenInfo * getScreenFromRoot(Window);
 extern void scanWindowTree(int);
 
-/*     client.c */
-extern Client *client_head(void);
+/*  client.c */
 extern Edge interacting_edge;
+extern Client *current;
+extern Client *Client_List(void);
 extern Client *Client_Get(Window);
 extern Client *Client_Add(Window, Window);
 extern void Client_MakeSane(Client *, Edge, int *, int *, int *, int *);
-extern void Client_DrawBorder(Client *, int);
-extern void setactive(Client *, int, long);
-extern void size_expose(void);
+extern void Client_DrawFrame(Client *, int);
+extern void Client_SetActive(Client *, int, long);
 extern void Client_ReshapeEdge(Client *, Edge);
 extern void Client_Move(Client*);
 extern void Client_SetState(Client *, int);
@@ -266,82 +176,40 @@ extern void Client_Raise(Client *);
 extern void Client_Lower(Client *);
 extern void Client_Close(Client *);
 extern void Client_Remove(Client *);
-extern void Client_FreeAll(void);
-extern void Client_ColourMap(XEvent*);
-extern void Client_EnterFullScreen(Client *c);
-extern void Client_ExitFullScreen(Client *c);
 extern void Client_Focus(Client *c, Time time);
 extern void Client_ResetAllCursors(void);
-extern void Client_Name(Client *c, const char *name, Bool is_utf8);
-extern int hidden(Client *);
-extern int withdrawn(Client *);
-extern int normal(Client *);
-extern void update_client_list(ScreenInfo *screen);
-extern Client *current;
+extern void Client_Name(Client *c, const char *name);
+extern int Client_IsState(Client*, int);
+extern int Client_HasFlags(Client*, int);
 
-/*     cursor.c */
+/*  cursor.c */
 extern Cursor getEdgeCursor(Edge edge);
 extern void initialiseCursors(int);
 
-/*     disp.c */
+/*  disp.c */
 extern void dispatch(XEvent *);
-extern void reshaping_motionnotify(XEvent *);
 
-/*     error.c */
+/*  error.c */
 extern int ignore_badwindow;
 extern int errorHandler(Display *, XErrorEvent *);
 extern void panic(char*);
 
-/*     manage.c */
+/*  manage.c */
 extern void getWindowName(Client *);
 extern void getNormalHints(Client *);
-extern Bool motifWouldDecorate(Client *);
 extern void manage(Client *, int);
 extern void withdraw(Client *);
-extern void cmapfocus(Client *);
-extern void getColourmaps(Client *);
 extern void getTransientFor(Client *);
-extern void Terminate(int);
 
-/*     mouse.c */
+/*  mouse.c */
 extern void getMousePosition(int *, int *);
-extern void hide(Client *);
-extern void unhidec(Client *, int);
-extern int menu_whichitem(int, int);
-extern void menuhit(XButtonEvent *);
-extern void unhide(int, int);
-extern void menu_expose(void);
-extern void menu_motionnotify(XEvent *);
-extern void menu_buttonrelease(XEvent *);
-
-/*     shape.c */
-extern int shapeEvent(XEvent *);
-extern int serverSupportsShapes(void);
-extern int isShaped(Window);
-extern void setShape(Client *);
-
-/*     resource.c */
-extern char *font_name;
-extern char *popup_font_name;
-extern char *btn1_command;
-extern char *btn2_command;
-extern int border;
-extern FocusMode focus_mode;
-extern char * sdup(char *);
-extern void parseResources(void);
 
-/*     ewmh.c */
+/*  ewmh.c */
 extern Atom ewmh_atom[];
 extern void ewmh_init(void);
 extern void ewmh_init_screens(void);
 extern EWMHWindowType ewmh_get_window_type(Window w);
 extern Bool ewmh_get_window_name(Client *c);
 extern Bool ewmh_hasframe(Client *c);
-extern void ewmh_set_state(Client *c);
-extern void ewmh_get_state(Client *c);
-extern void ewmh_change_state(Client *c, unsigned long action,
-       unsigned long atom);
 extern void ewmh_set_allowed(Client *c);
 extern void ewmh_set_client_list(ScreenInfo *screen);
-extern void ewmh_get_strut(Client *c);
-extern void ewmh_set_strut(ScreenInfo *screen);
diff --git a/lwm.man b/lwm.man
deleted file mode 100644 (file)
index a527498..0000000
--- a/lwm.man
+++ /dev/null
@@ -1,96 +0,0 @@
-.\" lwm, a window manager for X11
-.\" Copyright (C) 1997-2016 Elliott Hughes, James Carter
-.\" 
-.\" This program is free software; you can redistribute it and/or
-.\" modify it under the terms of the GNU General Public License
-.\" as published by the Free Software Foundation; either version 2
-.\" of the License, or (at your option) any later version.
-.\" 
-.\" This program is distributed in the hope that it will be useful,
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-.\" GNU General Public License for more details.
-.\" 
-.\" You should have received a copy of the GNU General Public License
-.\" along with this program; if not, write to the Free Software
-.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-.\" 
-.TH LWM 1
-.SH NAME
-lwm \- Lightweight Window Manager for the X Window System
-.SH SYNTAX
-\fBlwm \fP[ \fB\-s\fP \fIsession-id\fP ] 
-.SH DESCRIPTION
-\fILwm\fP is a window manager for the X Window System. It provides enough
-features to allow the user to manage their windows, and no more.
-.PP
-Windows are surrounded by a frame with a 
-titlebar at the top next to a small box. The frame is a grey colour for
-all windows except that which has the input focus, where it is black.
-.PP
-In the default configuration, \fIlwm\fP uses the enter-to-focus scheme, where
-moving the pointer into a window gives that window the input focus.
-\fILwm\fP may also be configured to use the click-to-focus scheme, where a
-window must be clicked on (with any button) to receive the input focus. Clicking
-on a window in this mode causes the window to be raised. Note that a click
-used to focus a window is always swallowed by \fIlwm\fP, so clicking a
-button in a new window requires two clicks.
-.PP
-A button 1 click on a window frame brings that window to the top. Dragging
-button 1 on the frame of a resizable window repositions that edge of
-the window. If a corner rather than an edge is dragged, then both edges
-forming the corner are repositioned. While you're reshaping a window,
-a little window pops up to show you the window's current size.
-.PP
-In the default configuration, button 1 on the root window does nothing.
-.PP
-Button 2 is used to drag a window by its frame, repositioning the window
-but maintaining its position in the window stack.
-.PP
-In the default configuration, button 2 on the root window brings up a
-new shell.
-.PP
-A button 3 click on a window frame hides that window.  Pressing
-button 3 on the root window brings up a menu of all the hidden windows.
-Releasing the button while over an item will unhide the named window.
-.PP
-A button 3 click in the frame while Shift is held down pushes the window
-to the back, under any other windows. (Users with 4-button mice are
-encouraged to use their fourth button for this function.)
-.PP
-A click with any button inside the little white box in a window's frame
-can be used to close the window.
-.SH OPTIONS
-\fILwm\fP accepts the following command line options:
-.PP
-.TP 8
-.B \-s
-specifies a client ID for the X Session Management system, and is used
-exclusively by session managers.
-.SH RESOURCES
-\fILwm\fP understands the following X resources:
-.TP 12
-.B titlefont
-font used in window titles
-.TP 12
-.B popupFont
-font used in popup window (menu/size indicator)
-.TP 12
-.B border
-width in pixels of window borders
-.TP 12
-.B button1
-program spawned when button 1 is clicked on the root window
-.TP 12
-.B button2
-program spawned when button 2 is clicked on the root window
-.TP 12
-.B focus
-focus mode, one of "enter" for enter-to-focus (or sloppy focus), or
-"click" for click-to-focus
-.SH "SEE ALSO"
-.PP
-X(7)
-.SH AUTHORS
-Elliott Hughes <ehughes@bluearc.com>,
-James Carter <james@jfc.org.uk>
index 9f8e4f9a37cb8f6d55f7b163029b440db1aac2ae..26ba3b53af6e7fb3bc1e1fa021e100cd2f23cd8b 100644 (file)
--- a/manage.c
+++ b/manage.c
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
 
-/* These are Motif definitions from Xm/MwmUtil.h, but Motif isn't available
-   everywhere. */
-#define MWM_HINTS_FUNCTIONS     (1L << 0)
-#define MWM_HINTS_DECORATIONS   (1L << 1)
-#define MWM_HINTS_INPUT_MODE    (1L << 2)
-#define MWM_HINTS_STATUS        (1L << 3)
-#define MWM_DECOR_ALL           (1L << 0)
-#define MWM_DECOR_BORDER        (1L << 1)
-#define MWM_DECOR_RESIZEH       (1L << 2)
-#define MWM_DECOR_TITLE         (1L << 3)
-#define MWM_DECOR_MENU          (1L << 4)
-#define MWM_DECOR_MINIMIZE      (1L << 5)
-#define MWM_DECOR_MAXIMIZE      (1L << 6)
-
 #include "lwm.h"
 
 static int getProperty(Window, Atom, Atom, long, unsigned char **);
@@ -50,560 +36,372 @@ static void applyGravity(Client *);
 void
 manage(Client * c, int mapped)
 {
-       int state;
-       XWMHints * hints;
-       XWindowAttributes current_attr;
-       XSetWindowAttributes attr;
-
-       /* For WM_PROTOCOLS handling. */
-       Atom * protocols;
-       int n;
-       int p;
-
-       /* Where auto-placement is going to put the next window. */
-       static int      auto_x = 100;
-       static int      auto_y = 100;
-
-       /* get the EWMH window type, as this might overrule some hints */
-       c->wtype = ewmh_get_window_type(c->window);
-       /* get in the initial EWMH state */
-       ewmh_get_state(c);
-       /* set EWMH allowable actions, now we intend to manage this window */
-       ewmh_set_allowed(c);
-       /* is this window to have a frame? */
-       if (c->wtype == WTypeNone) {
-               /* this breaks the ewmh spec (section 5.6) because in the
-                * absence of a _NET_WM_WINDOW_TYPE, _WM_WINDOW_TYPE_NORMAL
-                * must be taken. bummer.
-                */
-               c->framed = motifWouldDecorate(c);
-       } else {
-               c->framed = ewmh_hasframe(c);
-       }
-       if (isShaped(c->window)) c->framed = False;
-
-       /* get the EWMH strut - if there is one */
-       ewmh_get_strut(c);
-
-       /*
-        * Get the hints, window name, and normal hints (see ICCCM
-        * section 4.1.2.3).
-        */
-       hints = XGetWMHints(dpy, c->window);
-
-       getWindowName(c);
-       getNormalHints(c);
-
-       /*
-        * Get the colourmaps associated with this window. Get the window
-        * attribute colourmap first, then look to see if the
-        * WM_COLORMAP_WINDOWS property has been used to specify
-        * windows needing colourmaps that differ from the top-level
-        * colourmap. (See ICCCM section 4.1.8.)
-        */
-       XGetWindowAttributes(dpy, c->window, &current_attr);
-       c->cmap = current_attr.colormap;
-
-       getColourmaps(c);
-
-       /*
-        * Scan the list of atoms on WM_PROTOCOLS to see which of the
-        * protocols that we understand the client is prepared to
-        * participate in. (See ICCCM section 4.1.2.7.)
-        */
-       if (XGetWMProtocols(dpy, c->window, &protocols, &n) != 0) {
-               for (p = 0; p < n; p++) {
-                       if (protocols[p] == wm_delete) {
-                               c->proto |= Pdelete;
-                       } else if (protocols[p] == wm_take_focus) {
-                               c->proto |= Ptakefocus;
-                       }
-               }
-
-               XFree(protocols);
-       }
-
-       /* Get the WM_TRANSIENT_FOR property (see ICCCM section 4.1.2.6). */
-       getTransientFor(c);
-
-       /* Work out details for the Client structure from the hints. */
-       if (hints && (hints->flags & InputHint))
-               c->accepts_focus = hints->input;
-       if (c->proto | Ptakefocus)
-               /* WM_TAKE_FOCUS overrides normal hints */
-               c->accepts_focus = True;
-
-       if (!getWindowState(c->window, &state))
-               state = hints ? hints->initial_state : NormalState;
-
-       /*
-        *      Sort out the window's position.
-        */
-       {
-               Window root_window;
-               int x, y;
-               unsigned int w, h;
-               unsigned int border_width, depth;
-
-               XGetGeometry(dpy, c->window, &root_window, &x, &y, &w, &h,
-                       &border_width, &depth);
-
-               /*
-                * Do the size first.
-                *
-                * "The size specifiers refer to the width and height of the
-                * client excluding borders" -- ICCCM 4.1.2.3.
-                */
-               c->size.width  = w;
-               c->size.height = h;
-               if (c->framed == True) {
-                       c->size.width  += 2 * border;
-                       c->size.height += 2 * border;
-               }
-
-               /*
-                * THIS IS A HACK!
-                *
-                * OpenGL programs have a habit of appearing smaller than their
-                * minimum sizes, which they don't like.
-                */
-               if (c->size.width < c->size.min_width)
-                       c->size.width = c->size.min_width;
-               if (c->size.height < c->size.min_height)
-                       c->size.height = c->size.min_height;
-
-               /* Do the position next. */
-
-               /*
-                * If we have a user-specified position for a top-level window,
-                * or a program-specified position for a dialogue box, we'll
-                * take it. We'll also just take it during initialisation,
-                * since the previous manage probably placed its windows
-                * sensibly.
-                */
-               if (c->trans != None && c->size.flags & PPosition) {
-                       /* It's a "dialogue box". Trust it. */
-                       c->size.x = x;
-                       c->size.y = y;
-               } else if ((c->size.flags & USPosition) ||
-                       c->framed == False || mode == wm_initialising ) {
-                       /* Use the specified window position. */
-                       c->size.x = x;
-                       c->size.y = y;
-
-                       /*
-                        * We need to be careful of the right-hand edge and
-                        * bottom. We can use the window gravity (if specified)
-                        * to handle this. (See section 4.1.2.3 of the ICCCM.)
-                        */
-                       applyGravity(c);
-               } else {
-                       /* No position was specified: use the auto-placement
-                        * heuristics. */
-
-                       /* firstly, make sure auto_x and auto_y are outside
-                        * strut */
-                       if (auto_x < c->screen->strut.left)
-                               auto_x = c->screen->strut.left;
-                       if (auto_y < c->screen->strut.top)
-                               auto_y = c->screen->strut.top;
-
-                       if ((auto_x + c->size.width) >
-                               (c->screen->display_width -
-                               c->screen->strut.right) &&
-                               (c->size.width <=
-                               (c->screen->display_width -
-                               c->screen->strut.left -
-                               c->screen->strut.right))) {
-                               /*
-                                * If the window wouldn't fit using normal
-                                * auto-placement but is small enough to fit
-                                * horizontally, then centre the window
-                                * horizontally.
-                                */
-                               c->size.x = (c->screen->display_width
-                                       - c->size.width) / 2;
-                               auto_x = c->screen->strut.left + 20;
-                       } else {
-                               c->size.x = auto_x;
-                               auto_x += 10;
-                               if (auto_x > (c->screen->display_width / 2))
-                                       auto_x = c->screen->strut.left + 20;
-                       }
-
-                       if (((auto_y + c->size.height) >
-                               (c->screen->display_height -
-                               c->screen->strut.bottom)) &&
-                               (c->size.height <=
-                               (c->screen->display_height -
-                               c->screen->strut.top -
-                               c->screen->strut.bottom))) {
-                               /*
-                                * If the window wouldn't fit using normal
-                                * auto-placement but is small enough to fit
-                                * vertically, then centre the window
-                                * vertically.
-                                */
-                                c->size.y = (c->screen->display_height
-                                       - c->size.height) / 2;
-                                auto_y = c->screen->strut.top + 20;
-                       } else {
-                               c->size.y = auto_y;
-                               auto_y += 10;
-                               if (auto_y > (c->screen->display_height / 2))
-                                       auto_y = c->screen->strut.top + 20;
-                       }
-               }
-       }
-
-       if (hints)
-               XFree(hints);
-
-       /*
-        * Do all the reparenting and stuff.
-        */
-
-       if (c->framed == True) {
-               c->parent = XCreateSimpleWindow(dpy, c->screen->root,
-                       c->size.x, c->size.y - titleHeight(),
-                       c->size.width, c->size.height + titleHeight(),
-                       1, c->screen->black, c->screen->white);
-
-               attr.event_mask = ExposureMask | EnterWindowMask | ButtonMask |
-                       SubstructureRedirectMask | SubstructureNotifyMask |
-                       PointerMotionMask;
-               XChangeWindowAttributes(dpy, c->parent, CWEventMask, &attr);
-
-               XResizeWindow(dpy, c->window, c->size.width - 2 * border,
-                       c->size.height - 2 * border);
-       }
-
-       /*
-        * Stupid X11 doesn't let us change border width in the above
-        * call. It's a window attribute, but it's somehow second-class.
-        *
-        * As pointed out by Adrian Colley, we can't change the window
-        * border width at all for InputOnly windows.
-        */
-       if (current_attr.class != InputOnly)
-               XSetWindowBorderWidth(dpy, c->window, 0);
-
-       attr.event_mask = ColormapChangeMask | EnterWindowMask |
-               PropertyChangeMask | FocusChangeMask;
-       attr.win_gravity = StaticGravity;
-       attr.do_not_propagate_mask = ButtonMask;
-       XChangeWindowAttributes(dpy, c->window,
-               CWEventMask | CWWinGravity | CWDontPropagate, &attr);
-
-       if (c->framed == True) {
-               XReparentWindow(dpy, c->window, c->parent,
-                       border, border + titleHeight());
-       } else {
-               XReparentWindow(dpy, c->window, c->parent,
-                       c->size.x, c->size.y);
-       }
-
-       setShape(c);
-
-       XAddToSaveSet(dpy, c->window);
-       if (state == IconicState) {
-       } else {
-               /* Map the new window in the relevant state. */
-               c->hidden = False;
-               XMapWindow(dpy, c->parent);
-               XMapWindow(dpy, c->window);
-               setactive(c, (focus_mode == focus_click) ? 1 : 0, 0L);
-               Client_SetState(c, NormalState);
-       }
-
-       if (c->wstate.fullscreen == True) Client_EnterFullScreen(c);
-
-       if (current != c)
-               cmapfocus(current);
+    int state;
+    XWMHints * hints;
+    XWindowAttributes current_attr;
+    XSetWindowAttributes attr;
+
+    /* For WM_PROTOCOLS handling. */
+    Atom * protocols;
+    int n;
+    int p;
+
+    /* Where auto-placement is going to put the next window. */
+    static int  auto_x = 100;
+    static int  auto_y = 100;
+
+    /* get the EWMH window type, as this might overrule some hints */
+    c->wtype = ewmh_get_window_type(c->window);
+    /* set EWMH allowable actions, now we intend to manage this window */
+    ewmh_set_allowed(c);
+    /* is this window to have a frame? */
+    c->framed = ewmh_hasframe(c);
+
+    /*
+     * Get the hints, window name, and normal hints (see ICCCM
+     * section 4.1.2.3).
+     */
+    hints = XGetWMHints(dpy, c->window);
+
+    getWindowName(c);
+    getNormalHints(c);
+
+    /*
+     * Get the colourmaps associated with this window. Get the window
+     * attribute colourmap first, then look to see if the
+     * WM_COLORMAP_WINDOWS property has been used to specify
+     * windows needing colourmaps that differ from the top-level
+     * colourmap. (See ICCCM section 4.1.8.)
+     */
+    XGetWindowAttributes(dpy, c->window, &current_attr);
+
+    /*
+     * Scan the list of atoms on WM_PROTOCOLS to see which of the
+     * protocols that we understand the client is prepared to
+     * participate in. (See ICCCM section 4.1.2.7.)
+     */
+    if (XGetWMProtocols(dpy, c->window, &protocols, &n) != 0) {
+        for (p = 0; p < n; p++) {
+            if (protocols[p] == wm_delete) {
+                c->flags |= F_EWMH_DELETE;
+            } else if (protocols[p] == wm_take_focus) {
+                c->flags |= F_EWMH_TAKE_FOCUS;
+            }
+        }
+        XFree(protocols);
+    }
+
+    /* Get the WM_TRANSIENT_FOR property (see ICCCM section 4.1.2.6). */
+    getTransientFor(c);
+
+    /* Work out details for the Client structure from the hints. */
+    if (hints && (hints->flags & InputHint))
+        c->flags |= F_ACCEPT_FOCUS;
+    if (Client_HasFlags(c, F_EWMH_TAKE_FOCUS))
+        c->flags |= F_ACCEPT_FOCUS;
+
+    if (!getWindowState(c->window, &state))
+        state = hints ? hints->initial_state : NormalState;
+
+    /*
+     *  Sort out the window's position.
+     */
+    {
+        Window root_window;
+        int x, y;
+        unsigned int w, h;
+        unsigned int border_width, depth;
+
+        XGetGeometry(dpy, c->window, &root_window, &x, &y, &w, &h,
+            &border_width, &depth);
+
+        /*
+         * Do the size first.
+         *
+         * "The size specifiers refer to the width and height of the
+         * client excluding borders" -- ICCCM 4.1.2.3.
+         */
+        c->size.width  = w;
+        c->size.height = h;
+        if (c->framed == True) {
+            c->size.width  += 2 * border;
+            c->size.height += 2 * border;
+        }
+
+        /*
+         * THIS IS A HACK!
+         *
+         * OpenGL programs have a habit of appearing smaller than their
+         * minimum sizes, which they don't like.
+         */
+        if (c->size.width < c->size.min_width)
+            c->size.width = c->size.min_width;
+        if (c->size.height < c->size.min_height)
+            c->size.height = c->size.min_height;
+
+        /* Do the position next. */
+
+        /*
+         * If we have a user-specified position for a top-level window,
+         * or a program-specified position for a dialogue box, we'll
+         * take it. We'll also just take it during initialisation,
+         * since the previous manage probably placed its windows
+         * sensibly.
+         */
+        if (c->trans != None && c->size.flags & PPosition) {
+            /* It's a "dialogue box". Trust it. */
+            c->size.x = x;
+            c->size.y = y;
+        } else if ((c->size.flags & USPosition) ||
+            c->framed == False || mode == wm_initialising ) {
+            /* Use the specified window position. */
+            c->size.x = x;
+            c->size.y = y;
+
+            /*
+             * We need to be careful of the right-hand edge and
+             * bottom. We can use the window gravity (if specified)
+             * to handle this. (See section 4.1.2.3 of the ICCCM.)
+             */
+            applyGravity(c);
+        }
+    }
+
+    if (hints)
+        XFree(hints);
+
+    /*
+     * Do all the reparenting and stuff.
+     */
+
+    if (c->framed == True) {
+        c->parent = XCreateSimpleWindow(dpy, c->screen->root,
+            c->size.x, c->size.y - titleHeight(),
+            c->size.width, c->size.height + titleHeight(),
+            1, c->screen->black, c->screen->white);
+
+        attr.event_mask = ExposureMask | EnterWindowMask | ButtonMask |
+            SubstructureRedirectMask | SubstructureNotifyMask |
+            PointerMotionMask;
+        XChangeWindowAttributes(dpy, c->parent, CWEventMask, &attr);
+
+        XResizeWindow(dpy, c->window, c->size.width - 2 * border,
+            c->size.height - 2 * border);
+    }
+
+    /*
+     * Stupid X11 doesn't let us change border width in the above
+     * call. It's a window attribute, but it's somehow second-class.
+     *
+     * As pointed out by Adrian Colley, we can't change the window
+     * border width at all for InputOnly windows.
+     */
+    if (current_attr.class != InputOnly)
+        XSetWindowBorderWidth(dpy, c->window, 0);
+
+    attr.event_mask = EnterWindowMask |
+        PropertyChangeMask | FocusChangeMask;
+    attr.win_gravity = StaticGravity;
+    attr.do_not_propagate_mask = ButtonMask;
+    XChangeWindowAttributes(dpy, c->window,
+        CWEventMask | CWWinGravity | CWDontPropagate, &attr);
+
+    if (c->framed == True) {
+        XReparentWindow(dpy, c->window, c->parent,
+            border, border + titleHeight());
+    } else {
+        XReparentWindow(dpy, c->window, c->parent,
+            c->size.x, c->size.y);
+    }
+
+    XAddToSaveSet(dpy, c->window);
+    /* Map the new window in the relevant state. */
+    XMapWindow(dpy, c->parent);
+    XMapWindow(dpy, c->window);
+    Client_SetActive(c, 0, 0L);
+    Client_SetState(c, NormalState);
 }
 
 static void
 applyGravity(Client *c) {
-       if (c->framed == False) return; /* only required for framed windows*/
-       if (c->size.flags & PWinGravity) {
-               switch (c->size.win_gravity) {
-                       case NorthEastGravity:
-                               c->size.x -= 2 * border;
-                               break;
-                       case SouthWestGravity:
-                               c->size.y -= 2 * border;
-                               break;
-                       case SouthEastGravity:
-                               c->size.x -= 2 * border;
-                               c->size.y -= 2 * border;
-                               break;
-               }
-       }
+    if (c->framed == False) return; /* only required for framed windows*/
+    if (c->size.flags & PWinGravity) {
+        switch (c->size.win_gravity) {
+            case NorthEastGravity:
+                c->size.x -= 2 * border;
+                break;
+            case SouthWestGravity:
+                c->size.y -= 2 * border;
+                break;
+            case SouthEastGravity:
+                c->size.x -= 2 * border;
+                c->size.y -= 2 * border;
+                break;
+        }
+    }
 }
 
 void
 getTransientFor(Client *c) {
-       Window  trans = None;
+    Window  trans = None;
 
-       XGetTransientForHint(dpy, c->window, &trans);
-       c->trans = trans;
+    XGetTransientForHint(dpy, c->window, &trans);
+    c->trans = trans;
 }
 
 void
 withdraw(Client *c) {
-       if (c->parent != c->screen->root) {
-               XUnmapWindow(dpy, c->parent);
-               XReparentWindow(dpy, c->parent, c->screen->root, c->size.x, c->size.y);
-       }
-
-       XRemoveFromSaveSet(dpy, c->window);
-       Client_SetState(c, WithdrawnState);
-
-       /*
-        * Flush and ignore any errors. X11 sends us an UnmapNotify before it
-        * sends us a DestroyNotify. That means we can get here without knowing
-        * whether the relevant window still exists.
-        */
-       ignore_badwindow = 1;
-       XSync(dpy, False);
-       ignore_badwindow = 0;
-}
-
-static void
-installColourmap(Colormap cmap) {
-       if (cmap == None)
-               cmap = DefaultColormap(dpy, DefaultScreen(dpy));
-       XInstallColormap(dpy, cmap);
-}
-
-void
-cmapfocus(Client * c) {
-       int     i;
-       int     found;
-       Client  *cc;
-
-       if (c == 0)
-               installColourmap(None);
-       else if (c->ncmapwins != 0) {
-               found = 0;
-               for (i = c->ncmapwins - 1; i >= 0; i--) {
-                       installColourmap(c->wmcmaps[i]);
-                       if (c->cmapwins[i] == c->window)
-                               found++;
-               }
-               if (!found)
-                       installColourmap(c->cmap);
-       } else if (c->trans != None && (cc = Client_Get(c->trans)) != 0 &&
-           cc->ncmapwins != 0)
-               cmapfocus(cc);
-       else
-               installColourmap(c->cmap);
-}
-
-void
-getColourmaps(Client *c) {
-       int     n;
-       int     i;
-       Window  *cw;
-       XWindowAttributes       attr;
-
-       if (c == 0)
-               return;
-
-       n = getProperty(c->window, wm_colormaps, XA_WINDOW, 100L, (unsigned char **) &cw);
-       if (c->ncmapwins != 0) {
-               XFree(c->cmapwins);
-               free(c->wmcmaps);
-       }
-       if (n <= 0) {
-               c->ncmapwins = 0;
-               return;
-       }
-       c->ncmapwins = n;
-       c->cmapwins = cw;
-
-       c->wmcmaps = (Colormap *) malloc(n * sizeof(Colormap));
-       for (i = 0; i < n; i++) {
-               if (cw[i] == c->window) {
-                       c->wmcmaps[i] = c->cmap;
-               } else {
-                       XSelectInput(dpy, cw[i], ColormapChangeMask);
-                       XGetWindowAttributes(dpy, cw[i], &attr);
-                       c->wmcmaps[i] = attr.colormap;
-               }
-       }
-}
-
-/*ARGSUSED*/
-void
-Terminate(int signal) {
-       /* Set all clients free. */
-       Client_FreeAll();
-
-       /* Give up the input focus and the colourmap. */
-       XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
-       installColourmap(None);
-
-       XCloseDisplay(dpy);
-       exit(signal ? EXIT_FAILURE : EXIT_SUCCESS);
+    if (c->parent != c->screen->root) {
+        XUnmapWindow(dpy, c->parent);
+        XReparentWindow(dpy, c->parent, c->screen->root, c->size.x, c->size.y);
+    }
+
+    XRemoveFromSaveSet(dpy, c->window);
+    Client_SetState(c, WithdrawnState);
+
+    /*
+     * Flush and ignore any errors. X11 sends us an UnmapNotify before it
+     * sends us a DestroyNotify. That means we can get here without knowing
+     * whether the relevant window still exists.
+     */
+    ignore_badwindow = 1;
+    XSync(dpy, False);
+    ignore_badwindow = 0;
 }
 
-
 static int
 getProperty(Window w, Atom a, Atom type, long len, unsigned char **p) {
-       Atom    real_type;
-       int     format;
-       unsigned long   n;
-       unsigned long   extra;
-       int     status;
-
-       /*
-        *      len is in 32-bit multiples.
-        */
-       status = XGetWindowProperty(dpy, w, a, 0L, len, False, type, &real_type, &format, &n, &extra, p);
-       if (status != Success || *p == 0)
-               return -1;
-       if (n == 0)
-               XFree(*p);
-       /*
-        *      could check real_type, format, extra here...
-        */
-       return n;
+    Atom    real_type;
+    int format;
+    unsigned long   n;
+    unsigned long   extra;
+    int status;
+
+    /*
+     *  len is in 32-bit multiples.
+     */
+    status = XGetWindowProperty(dpy, w, a, 0L, len, False, type, &real_type, &format, &n, &extra, p);
+    if (status != Success || *p == 0)
+        return -1;
+    if (n == 0)
+        XFree(*p);
+    /*
+     *  could check real_type, format, extra here...
+     */
+    return n;
 }
 
 void
 getWindowName(Client *c) {
-       char * name;
-       Atom actual_type;
-       int format;
-       unsigned long n;
-       unsigned long extra;
-       int was_nameless;
-
-       if (c == 0)
-               return;
-
-       was_nameless = (c->name == 0);
-
-       if (ewmh_get_window_name(c) == False &&
-               XGetWindowProperty(dpy, c->window, _mozilla_url, 0L, 100L, False, AnyPropertyType, &actual_type, &format, &n, &extra, (unsigned char **) &name) == Success && name && *name != '\0' && n != 0) {
-               Client_Name(c, name, False);
-               XFree(name);
-       } else if (XGetWindowProperty(dpy, c->window, XA_WM_NAME, 0L, 100L, False, AnyPropertyType, &actual_type, &format, &n, &extra, (unsigned char **) &name) == Success && name && *name != '\0' && n != 0) {
-               /* That rather unpleasant condition is necessary because xwsh uses
-               * COMPOUND_TEXT rather than STRING for its WM_NAME property,
-               * and anonymous xwsh windows are annoying.
-               */
-               if (actual_type == compound_text && memcmp(name, "\x1b\x28\x42", 3) == 0) {
-                       Client_Name(c, name + 3, False);
-               } else {
-                       Client_Name(c, name, False);
-               }
-               XFree(name);
-       }
-
-       if (!was_nameless)
-               Client_DrawBorder(c, c == current);
+    char * name;
+    Atom actual_type;
+    int format;
+    unsigned long n;
+    unsigned long extra;
+    int was_nameless;
+
+    if (c == 0)
+        return;
+
+    was_nameless = (c->name == 0);
+
+    if (ewmh_get_window_name(c) == False) {
+        if (XGetWindowProperty(dpy, c->window, XA_WM_NAME, 0L, 100L, False, AnyPropertyType, &actual_type, &format, &n, &extra, (unsigned char **) &name) == Success && name && *name != '\0' && n != 0) {
+            /* That rather unpleasant condition is necessary because xwsh uses
+            * COMPOUND_TEXT rather than STRING for its WM_NAME property,
+            * and anonymous xwsh windows are annoying.
+            */
+            if (actual_type == compound_text && memcmp(name, "\x1b\x28\x42", 3) == 0) {
+                Client_Name(c, name + 3);
+            } else {
+                Client_Name(c, name);
+            }
+            XFree(name);
+        }
+    }
+
+    if (!was_nameless)
+        Client_DrawFrame(c, c == current);
 }
 
 void
 getNormalHints(Client *c) {
-       int x, y, w, h;
-       long msize;
-
-       /* We have to be a little careful here. The ICCCM says that the x, y
-        * and width, height components aren't used. So we use them. That means
-        * that we need to save and restore them whenever we fill the size
-        * struct. */
-       x = c->size.x;
-       y = c->size.y;
-       w = c->size.width;
-       h = c->size.height;
-
-       /* Do the get. */
-       if (XGetWMNormalHints(dpy, c->window, &c->size, &msize) == 0)
-               c->size.flags = 0;
-
-       if (c->framed == True) {
-               /*
-               * Correct the minimum allowable size of this client to take
-               * account of the window border.
-               */
-               if (c->size.flags & PMinSize) {
-                       c->size.min_width  += 2 * border;
-                       c->size.min_height += 2 * border;
-               } else {
-                       c->size.flags |= PMinSize;
-                       c->size.min_width  = 2 * (2 * border);
-                       if (c->accepts_focus)
-                               c->size.min_height = 2 * (2*border);
-                       else
-                               c->size.min_height = 2 * (2*border);
-               }
-
-               /*
-               * Correct the maximum allowable size of this client to take
-               * account of the window border.
-               */
-               if (c->size.flags & PMaxSize) {
-                       c->size.max_width  += 2 * border;
-                       c->size.max_height += 2 * border;
-               }
-       }
-
-       /*
-        * Ensure that the base width & height and the width & height increments
-        * are set correctly so that we don't have to do this in MakeSane.
-        */
-       if (!(c->size.flags & PBaseSize))
-               c->size.base_width = c->size.base_height = 0;
-
-       if (!(c->size.flags & PResizeInc))
-               c->size.width_inc = c->size.height_inc = 1;
-
-       /*
-        * If the client gives identical minimum and maximum sizes, we don't
-        * want the user to resize in that direction.
-        */
-       if (c->size.min_width == c->size.max_width)
-               c->size.width_inc = 0;
-
-       if (c->size.min_height == c->size.max_height)
-               c->size.height_inc = 0;
-
-       /* Restore the window-manager bits. */
-       c->size.x = x;
-       c->size.y = y;
-       c->size.width = w;
-       c->size.height = h;
+    int x, y, w, h;
+    long msize;
+
+    /* We have to be a little careful here. The ICCCM says that the x, y
+     * and width, height components aren't used. So we use them. That means
+     * that we need to save and restore them whenever we fill the size
+     * struct. */
+    x = c->size.x;
+    y = c->size.y;
+    w = c->size.width;
+    h = c->size.height;
+
+    /* Do the get. */
+    if (XGetWMNormalHints(dpy, c->window, &c->size, &msize) == 0)
+        c->size.flags = 0;
+
+    if (c->framed == True) {
+        /*
+        * Correct the minimum allowable size of this client to take
+        * account of the window border.
+        */
+        if (c->size.flags & PMinSize) {
+            c->size.min_width  += 2 * border;
+            c->size.min_height += 2 * border;
+        } else {
+            c->size.flags |= PMinSize;
+            c->size.min_width  = 2 * (2 * border);
+            c->size.min_height = 2 * (2 * border);
+        }
+
+        /*
+        * Correct the maximum allowable size of this client to take
+        * account of the window border.
+        */
+        if (c->size.flags & PMaxSize) {
+            c->size.max_width  += 2 * border;
+            c->size.max_height += 2 * border;
+        }
+    }
+
+    /*
+     * Ensure that the base width & height and the width & height increments
+     * are set correctly so that we don't have to do this in MakeSane.
+     */
+    if (!(c->size.flags & PBaseSize))
+        c->size.base_width = c->size.base_height = 0;
+
+    if (!(c->size.flags & PResizeInc))
+        c->size.width_inc = c->size.height_inc = 1;
+
+    /*
+     * If the client gives identical minimum and maximum sizes, we don't
+     * want the user to resize in that direction.
+     */
+    if (c->size.min_width == c->size.max_width)
+        c->size.width_inc = 0;
+
+    if (c->size.min_height == c->size.max_height)
+        c->size.height_inc = 0;
+
+    /* Restore the window-manager bits. */
+    c->size.x = x;
+    c->size.y = y;
+    c->size.width = w;
+    c->size.height = h;
 }
 
 static int
 getWindowState(Window w, int *state) {
-       long    *p = 0;
+    long    *p = 0;
 
-       if (getProperty(w, wm_state, wm_state, 2L, (unsigned char **) &p) <= 0)
-               return 0;
+    if (getProperty(w, wm_state, wm_state, 2L, (unsigned char **) &p) <= 0)
+        return 0;
 
-       *state = (int) *p;
-       XFree(p);
-       return 1;
+    *state = (int) *p;
+    XFree(p);
+    return 1;
 }
 
-
-extern Bool
-motifWouldDecorate(Client *c) {
-       unsigned long *p = 0;
-       Bool ret = True; /* if all else fails - decorate */
-
-       if (getProperty(c->window, motif_wm_hints, motif_wm_hints,
-               5L, (unsigned char **) &p) <= 0)
-               return ret;
-
-       if ((p[0] & MWM_HINTS_DECORATIONS) &&
-               !(p[2] & (MWM_DECOR_BORDER | MWM_DECOR_ALL)))
-               ret = False;
-
-       XFree(p);
-       return ret;
-}
diff --git a/shape.c b/mouse.c
similarity index 73%
rename from shape.c
rename to mouse.c
index 2b06189da046be3f1ead22a60bdc8c7354bbfa92..6ab33b35ff49618393455b0beede71b07201dba4 100644 (file)
--- a/shape.c
+++ b/mouse.c
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <unistd.h>
 
 #include <X11/X.h>
+#include <X11/Xos.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
-#ifdef SHAPE
-#include <X11/extensions/shape.h>
-#endif
 
 #include "lwm.h"
+#include "ewmh.h"
 
-/*ARGSUSED*/
-extern void
-setShape(Client *c) {
-}
+void
+getMousePosition(int * x, int * y) {
+    Window root, child;
+    int t1, t2;
+    unsigned int b;
 
-/*ARGSUSED*/
-extern int
-shapeEvent(XEvent *ev) {
-       return 0;
+    /* It doesn't matter which root window we give this call. */
+    XQueryPointer(dpy, screens[0].root, &root, &child, x, y, &t1, &t2, &b);
+    current_screen = getScreenFromRoot(root);
 }
 
-/*ARGSUSED*/
-extern int
-isShaped(Window w) {
-       return 0;
-}
-
-extern int
-serverSupportsShapes(void) {
-       return 0;
-}
diff --git a/no_xmkmf_makefile b/no_xmkmf_makefile
deleted file mode 100644 (file)
index d184e5c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#      Sample Makefile for lwm.
-
-#      You ought to be using the Imakefile (xmkmf;make) but
-#      if Imake isn't set up properly on your system, this might
-#      help you out. I used to use it on an SGI.
-
-# Uncomment these lines to use gcc.
-#CC = gcc
-#CFLAGS = -ansi -pedantic -Wall -DSHAPE
-
-# Uncomment these lines to use SGI cc.
-#CC = cc
-#CFLAGS = -fullwarn -g -DSHAPE
-
-# Uncomment these for Solaris Sun Studio, choose your architecture.
-#CC = cc
-#CFLAGS = -Xa -fast -xarch=v8a
-#CFLAGS = -Xa -fast -xarch=386
-
-DEFINES = 
-
-# Bennett Todd (bet@lehman.com) says this helped him compile on
-# Solaris 2.5.1, avoiding a problem with <sys/signal.h>.
-#DEFINES = -D_POSIX_C_SOURCE=2
-
-# Add any strange libraries your system needs here.
-LDFLAGS = -lXext -lX11 -lICE -lSM
-
-# -----------------------------------------------------------------------------
-
-OFILES = client.o cursor.o disp.o error.o ewmh.o lwm.o manage.o mouse.o \
-       resource.o session.o shape.o
-HFILES = lwm.h ewmh.h
-
-# -----------------------------------------------------------------------------
-
-all: lwm
-
-lwm: $(OFILES)
-       $(CC) $(CFLAGS) $(DEFINES) -o lwm $(OFILES) $(LDFLAGS)
-
-install: lwm
-       cp lwm /usr/local/bin
-
-$(OFILES): $(HFILES)
-
-clean:
-       rm -f lwm *.o core