On Sun 18 May 2014 at 19:52:12 -0000, [email protected] wrote:
> The mention of WM_TAKE_FOCUS brought back memory about
> another piece of information I found about this.

Looking at the source, it seems that ctwm does try to send the
WM_TAKE_FOCUS messages, but there may be an interaction with the
TitleFocus option, which is default on (unless you have ClickToFocus).

Unfortunately, the code which processes the NoTitleFocus word in .ctwm
has somehow been changed to turn the option ON instead of OFF...

In any case, I tried the test program in C which is attached at 

>   http://code.google.com/p/xmonad/issues/detail?id=177

and that seems to function as expected, with my setup at least.
For the record I attach it to this may, if it's ever needed.

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert  -- The Doctor: No, 'eureka' is Greek for
\X/ rhialto/at/xs4all.nl    -- 'this bath is too hot.'
# /*
gcc -I /usr/X11R7/include -L/usr/X11R7/lib -R/usr/X11R7/lib -lX11 native.c -o 
native
exit $?

    This test program is from
    https://code.google.com/p/xmonad/issues/detail?id=177

    === Quote from there: ===
    I've done an investigation together with Java AWT engineers and we've found
    that this is a problem in xmonad, not in Java. The problem is that xmonad
    ignores the WM_TAKE_FOCUS protocol which is described in the ICCCM (see
    http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7).

    Java sets <Globally Active> model for its Frames/Dialogs, and <No Input>
    model for its Windows. In both of these cases the WM shouldn't call
    XSetInputFocus by itself. In the former case it should send the
    WM_TAKE_FOCUS event to the window (when it decides that the toplevel window
    should get the focus), in the latter case it shouldn't do anything (Java
    processes all the clicks by itself).

    See also the attached C file. You can compile it using the following 
command:
    gcc -o native -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 native.c

    When run, this file file prints the FocusIn/FocusOut events and also it
    prints WM_TAKE_FOCUS events if they are sent. The correct behaviour of this
    program in the WM is to print the message "event on frame %i:
    WM_TAKE_FOCUS" (where %i is the number of frame, 0 or 1 in this program)
    whenever the focus is set to its window using the WM (either using keys, or
    mouse). Incorrect behaviour is when it prints only pairs of the
    "FocusIn"/"FocusOut" messages.

    I tried reproducing the same problem in IceWM and found that it handles the
    WM_TAKE_FOCUS protocol correctly (both on this test program and on real
    applications).
    === End Quote ===
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include <stdio.h>

Display *display;
int screen_num;
Window root;
Atom XA_WM_TAKE_FOCUS;

Window create_window(char * name, Window parent, int x, int y, int width, int 
height) 
{
    XSizeHints sh;
    XWMHints wmh;
    Window win = XCreateSimpleWindow(display, parent, x, y, width, height,
                                     2, // border width
                                     BlackPixel(display, screen_num),
                                     WhitePixel(display, screen_num));          
       
    XStoreName(display, win, name);
    XSelectInput(display, win, FocusChangeMask | ButtonPressMask  | 
ButtonReleaseMask );
    
    sh.width = width;
    sh.height = height;
    sh.x = x;
    sh.y = y;
    sh.flags = USPosition | USSize;
    XSetWMNormalHints(display, win, &sh);

    wmh.input = False;
    wmh.flags = InputHint;
    XSetWMHints(display, win, &wmh);

    Atom protocols[1];
    protocols[0] = XA_WM_TAKE_FOCUS = XInternAtom (display, "WM_TAKE_FOCUS", 
True);
    XSetWMProtocols (display, win, protocols, 1);

    return win;
}

int main(int argc, char **argv)
{
    Window window, win;
    XEvent ev;

    char *display_name = NULL;
    if ((display = XOpenDisplay(display_name)) == NULL)
    {
        fprintf(stderr, "Couldn't open %s\n", XDisplayName(display_name));
        return -1;
    }
    screen_num = DefaultScreen(display);
    root = RootWindow(display, screen_num);

    window = create_window("TestFrame", root, 100, 100, 200, 100);

    XMapWindow(display, window);

    XFlush(display);
    XSync(display, False);

    while (1)
    {
        XNextEvent(display, &ev);

        int i = 0;
        for (i = 0; i < 2; i++) {

            win = ev.xany.window;
            if (win == window) {

                fprintf(stderr, "event on frame %i: ", i);

                switch(ev.xany.type) {

                case ClientMessage:
                    fprintf(stderr, "ClientMessage\n");
                    if (ev.xclient.data.l[0] == XA_WM_TAKE_FOCUS) {
                        fprintf(stderr, "  WM_TAKE_FOCUS\n");
                        XSetInputFocus(display, win, RevertToPointerRoot, 
CurrentTime);
                    }
                    break;
                case FocusIn:
                    fprintf(stderr, "FocusIn\n");
                    break;
                case FocusOut:
                    fprintf(stderr, "FocusOut\n");
                    break;
                default:
                    fprintf(stderr, "%d\n", ev.xany.type);
                }
            }
        }
    }
    return 0;
}

Attachment: pgpBby_1LHb1G.pgp
Description: PGP signature

Reply via email to