简体   繁体   中英

window manager: Newly launched applications are not visible while the wm is running

TL;DR

I'm writing a simple reparenting window manager. I'm testing it with the help of Xephyr. While the window manager is running, any application launched during that time, is not shown (not visible) on the screen, whereas any application launched before the window manager was launched is shown (visible).

Full Question

I'm writing a simple reparenting window manager. Currently I'm handling only two events XCB_CREATE_NOTIFY and XCB_BUTTON_PRESS . I've registered for XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT and XCB_EVENT_MASK_EXPOSURE on the root window.

I'm testing the wm with Xephyr. And while testing any application launched after the wm has launched, is not shown (not visible) on the screen, while applications that have been launched before launching the wm, are shown perfectly (visible).

I read somewhere that registering for EXPOSURE event on the root window will solve the problem, but that doesn't seem the case for me. Below is my code for the CREATE_NOTIFY event, that attempts to reparent the client window and map it on screen (I think this is where I'm doing something wrong):

case XCB_CREATE_NOTIFY:
    {
        xcb_create_notify_event_t *cre;
        cre = (xcb_create_notify_event_t *)evt;

        xcb_window_t frame = xcb_generate_id(conn);
        uint32_t frameMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
        uint32_t fM_values[2];
        fM_values[0] = custTeal->pixel; //custTeal is a custom Teal color that I've defined
        fM_values[1] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION;

        xcb_window_t toBeMapped = cre->window;
        xcb_get_geometry_reply_t *tbm_window_geo = xcb_get_geometry_reply(conn,xcb_get_geometry(conn,toBeMapped),NULL);

        xcb_create_window(conn,0,frame,screen->root,tbm_window_geo->x,tbm_window_geo->y,(tbm_window_geo->width+4),(tbm_window_geo->height+4),1,XCB_WINDOW_CLASS_INPUT_OUTPUT,screen->root_visual,frameMask,fM_values);

        xcb_reparent_window(conn,toBeMapped,frame,2,2);

        xcb_map_window(conn,frame);
        xcb_map_window(conn,toBeMapped);

        xcb_flush(conn);
    }
    break;

I can't figure out what I'm doing wrong here (I'm pretty new to this). Do I have to handle the EXPOSE event too? How do I handle it?

Testing

Im launching Xephyr with

Xephyr -br -ac -noreset -screen 1240x720 :2 &

and launching new applications with (take xterm as an example):

DISPLAY=:2 xterm &

Now, any application launched before launching the wm (or when the wm is not running) is shown perfectly in Xephyr. But after I launch the wm, any application launched is not showm.

SubstructureRedirect means that when something else tries to map a window, the X11 server instead generated a MapRequest event and sends that to the WM. Thus, you should handle XCB_MAP_REQUEST events. The simplest way to do that would be to xcb_map_window the window from the event.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM