[Xquartz-dev] Apple-WM usage
xquartz-dev.5.mzs at spamgourmet.com
xquartz-dev.5.mzs at spamgourmet.com
Tue Apr 8 14:00:26 PDT 2008
Hi,
I have been investigating using a window manager other than quartz-wm.
There was a post to the Apple X11-users list about Apple-WM and it sparked
my curiousity. You can run 'man AppleWM' to see what I am talking about.
My idea was to patch an open source window manager so that it would do the
Apple-WM stuff optionally, so I started off by writing a little program to
do some Apple-WM stuff. It appears that few of the routines I call have
any effect sadly. I have attached the source file wm.c as an example. It
takes one option, the window id in hex which you can learn from something
like xwininfo or xlsclients:
I have an .xinitrc that ends like so:
quartz-wm --only-proxy &
exec blackbox
Then I run this:
grief:AppleWM mzs$ gcc aw.c -o aw -L/usr/X11/lib -lX11 -lAppleWM -DDEBUG
grief:AppleWM mzs$ xterm &
[1] 17560
grief:AppleWM mzs$ xlsclients -l
Window 0x20000d:
Machine: grief.fnal.gov
Name: xterm
Icon Name: xterm
Command: xterm
Instance/Class: xterm/XTerm
grief:AppleWM mzs$ ./aw 0x20000d
strtoul(0x20000d, NULL, 16): 0x20000d
XOpenDisplay(/tmp/launch-IbGgSt/:0): 0x800000
XAppleWMQueryExtension: 1
event base: 68, error base: 130
XAppleWMQueryVersion: 1
major: 1, minor 0, patch 0
True = 1, False = 0
XAppleWMSetCanQuit(dpy, False): 1
XAppleWMSetFrontProcess(dpy): 1
XAppleWMSetWindowLevel(dpy, window, 0): 1
XAppleWMSetFrontProcess(dpy): 1
XAppleWMSetWindowLevel(dpy, window, 0): 1
Even though all those are returning 'True' XAppleWMSetCanQuit,
XAppleWMSetFrontProcess, and XAppleWMSetWindowLevel appear to nat have any
effect.
An example of the rationale for doing this is so:
For example you would like X11.app to pop-up a dialog box asking you to
verify that you indeed wish to quit. So when you start-up your X11 session
would like to do the XAppleWMSetCanQuit function.
There are lots of other places the window manager would like to do other
Apple-WM specific things.
I have also tried to compile aw.c with -framework AppKit with no
difference in behavior. Is there something I am doing wrong? Does it have
to be the actual window manager that calls these? What is the future of
Apple-WM?
I wanted to see if Apple-WM was actually being used, so I created inter.c
which I have attached also. There is a comment at the beginning of the
source file that explains how I used it. I see in the log file that
XAppleWMSetCanQuit is being used by quartz-wm:
-[x_screen update_geometry]
-[x_screen update_geometry]: head 0: 0,22 1680x1028
-[x_screen update_geometry]: head 1: 1680,0 1280x1024
-[x_screen update_geometry]: main head has index 0
-[x_screen init_with_screen_id:]: 0, 2960x1050x24, root:44, 2 heads
-[x_screen adopt_window:initializing:]: 20000d
-[x_window init_with_id:screen:initializing:]: 20000d
-[x_window reparent_in]: 20000d
-[x_window update_shape:]: 20000d
-[x_window update_inner_windows:outer:inner:]: 20000d
-[x_window send_configure]: 20000d
-[x_window focus:raise:force:]: 20000d
XAppleWMSetCanQuit = 0x0x032780
XAppleWMFrameDraw = 0x0x031790
XAppleWMSetCanQuit: 0x810c00, 0
...
There is a bunch of Notify stuff with window 44 though, I wonder if that
has something to do with the use of AppleWM?
Oh I am currently running the more recent release candidate (rc2) and
there is that bug in this one where the Windows do not come forward until
the dock icon is clicked twice. Possibly quartx-wm is not doing the
XAppleWMSetWindowLevel stuff correctly itself.
What I was planning on doing was patching blackbox so that it would work
better in rootless mode on OS X. For example the aforementioned
XAppleWMSetCanQuit. Also behavior such as this:
When I click on an X11 window in the background it gets focus and comes to
the foreground.
When I hold down a modifier and drag an X11 window in the background it
gets focus and moves around but does not come to the forground.
etc...
I was hoping to ge this to work with the aid of Apple-WM but am having
trouble getting it to do anything at all at this point and would really
appreciate any helpful ideas.
Thanks,
mzs
-------------- next part --------------
/* gcc aw.c -o aw -L/usr/X11/lib -lX11 -lAppleWM */
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/applewm.h>
/* trick to verbosely do an expression */
#ifdef DEBUG
#define debug(expr, fmt, args...) \
((void)fprintf(stderr, fmt "\n", ## args, expr))
#else
#define debug(expr, fmt, args...) (void)(expr)
#endif
int
main(int argc, const char *argv[])
{
Display* dpy;
char *display;
Window window;
int event, error;
int major, minor, patch;
int level;
if (argc != 2) {
(void)fprintf(stderr, "Usage %s window\n", argv[0]);
return (2);
}
errno = 0;
debug(window = strtoul(argv[1], NULL, 16),
"strtoul(%s, NULL, 16): 0x%x", argv[1]);
if (errno != 0) {
perror(argv[0]);
return (1);
}
display = getenv("DISPLAY");
if (display == NULL)
display = ":0";
debug(dpy = XOpenDisplay(display),
"XOpenDisplay(%s): 0x%x", display);
if (dpy == NULL) {
(void)fprintf(stderr, "Cannot connect to X server %s\n",
display);
return (1);
}
debug(XAppleWMQueryExtension(dpy, &event, &error),
"XAppleWMQueryExtension: %d");
(void)printf("event base: %d, error base: %d\n", event, error);
debug(XAppleWMQueryVersion(dpy, &major, &minor, &patch),
"XAppleWMQueryVersion: %d");
(void)printf("major: %d, minor %d, patch %d\n", major, minor, patch);
debug(False, "True = %d, False = %d", True);
debug(XAppleWMSetCanQuit(dpy, False),
"XAppleWMSetCanQuit(dpy, False): %d");
level = AppleWMWindowLevelNormal;
debug(XAppleWMSetFrontProcess(dpy),
"XAppleWMSetFrontProcess(dpy): %d");
debug(XAppleWMSetWindowLevel(dpy, window, level),
"XAppleWMSetWindowLevel(dpy, window, %d): %d", level);
debug(XAppleWMSetFrontProcess(dpy),
"XAppleWMSetFrontProcess(dpy): %d");
debug(XAppleWMSetWindowLevel(dpy, window, level),
"XAppleWMSetWindowLevel(dpy, window, %d): %d", level);
return (0);
}
-------------- next part --------------
/*
* This is a library that interposes on Apple-WM for debugging of why AppleWM
* does not seem to work for me. Here is how you use it:
*
* Verify that you do not have libinter.dylib or quartz-wm.txt in your home dir
* as something you would not like to lose then:
*
* gcc -dynamiclib -o libinter.dylib inter.c
* cp libinter.dylib "$HOME"
*
* Open another terminal window and do this to see the log file:
*
* touch "$HOME"/quartz-wm.txt
* tail -f "$HOME"/quartz-wm.txt
*
* If you do not have an .xinitrc file, copy the system one to your home dir and
* modify it so that it runs this:
*
* DEBUG=1023; export DEBUG
* DYLD_FORCE_FLAT_NAMESPACE=1; export DYLD_FORCE_FLAT_NAMESPACE
* DYLD_INSERT_LIBRARIES="$HOME"/libinter.dylib; export DYLD_INSERT_LIBRARIES
* exec quartz-wm 2>"$HOME"/quartz-wm.txt
*
* Now fire-up X11 with something like xlsclients and experiment.
*/
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <X11/Xlib.h>
#include <X11/extensions/applewm.h>
/* RTLD_NEXT does not seem to work, so I'll just dlopen it myself */
static const char dylib[] = "/usr/X11/lib/libAppleWM.dylib";
static Bool (*setcanquit)(Display *, Bool) = NULL;
static Bool (*framedraw)(
Display *, int, Window, unsigned int, unsigned int,
short, short, short, short, short, short, short, short,
unsigned int, const unsigned char*
) = NULL;
/* return address with symbol name n from handle h */
static void *
addr(void *h, const char *n)
{
void *a;
a = dlsym(h, n);
if (a == NULL) {
(void)fprintf(stderr, "%s: %s\n", n, dlerror());
exit(2);
}
(void)fprintf(stderr, "%s = 0x%08p\n", n, a);
return (a);
}
static void
init(void)
{
void *lh;
lh = dlopen(dylib, RTLD_GLOBAL);
if (lh == NULL) {
(void)fprintf(stderr, "%: %s\n", dylib, dlerror());
exit(2);
}
setcanquit = addr(lh, "XAppleWMSetCanQuit");
framedraw = addr(lh, "XAppleWMFrameDraw");
}
Bool
XAppleWMSetCanQuit(Display *dpy, Bool state)
{
if (setcanquit == NULL)
init();
(void)fprintf(stderr, "XAppleWMSetCanQuit: %p, %d\n", dpy, state);
return (setcanquit(dpy, state));
}
int
XAppleWMFrameDraw(
Display *dpy, int screen,
Window window,
unsigned int frame_class,
unsigned int frame_attr,
short inner_x, short inner_y,
short inner_w, short inner_h,
short outer_x, short outer_y,
short outer_w, short outer_h,
unsigned int title_length,
const unsigned char *title_bytes)
{
if (framedraw == NULL)
init();
(void)fprintf(stderr, "XAppleWMFrameDraw: "
"%p, %d, 0x%x, 0x%x, 0x%x, "
"%hd, %hd, %hd, %hd, %hd, %hd, %hd, %hd, "
"%d, %.*s\n",
dpy, screen, window, frame_class, frame_attr,
inner_x, inner_y, inner_w, inner_h,
outer_x, outer_y, outer_w, outer_h,
title_length, title_length, title_bytes);
return (framedraw(dpy, screen, window, frame_class,
frame_attr, inner_x, inner_y, inner_w, inner_h,
outer_x, outer_y, outer_w, outer_h,
title_length, title_bytes));
}
More information about the Xquartz-dev
mailing list