X11/Xlib: Window always on top

前端 未结 4 1267
庸人自扰
庸人自扰 2020-12-30 18:35

A window should stay on top of all other windows. Is this somehow possible with plain x11/xlib? Googling for \"Always on top\" and \"x11\" / \"xlib\" didn\'t return anything

相关标签:
4条回答
  • 2020-12-30 18:53
    #define _NET_WM_STATE_REMOVE        0    // remove/unset property
    #define _NET_WM_STATE_ADD           1    // add/set property
    #define _NET_WM_STATE_TOGGLE        2    // toggle property
    ...
    ...
    Atom wmStateAbove = XInternAtom( display, "_NET_WM_STATE_ABOVE", 1 );
    if( wmStateAbove != None ) {
        printf( "_NET_WM_STATE_ABOVE has atom of %ld\n", (long)wmStateAbove );
    } else {
        printf( "ERROR: cannot find atom for _NET_WM_STATE_ABOVE !\n" );
    }
    
    Atom wmNetWmState = XInternAtom( display, "_NET_WM_STATE", 1 );
    if( wmNetWmState != None ) {
        printf( "_NET_WM_STATE has atom of %ld\n", (long)wmNetWmState );
    } else {
        printf( "ERROR: cannot find atom for _NET_WM_STATE !\n" );
    }
    // set window always on top hint
    if( wmStateAbove != None ) {
        XClientMessageEvent xclient;
        memset( &xclient, 0, sizeof (xclient) );
        //
        //window  = the respective client window
        //message_type = _NET_WM_STATE
        //format = 32
        //data.l[0] = the action, as listed below
        //data.l[1] = first property to alter
        //data.l[2] = second property to alter
        //data.l[3] = source indication (0-unk,1-normal app,2-pager)
        //other data.l[] elements = 0
        //
        xclient.type = ClientMessage;
        xclient.window = mywin; // GDK_WINDOW_XID(window);
        xclient.message_type = wmNetWmState; //gdk_x11_get_xatom_by_name_for_display( display, "_NET_WM_STATE" );
        xclient.format = 32;
        xclient.data.l[0] = _NET_WM_STATE_ADD; // add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
        xclient.data.l[1] = wmStateAbove; //gdk_x11_atom_to_xatom_for_display (display, state1);
        xclient.data.l[2] = 0; //gdk_x11_atom_to_xatom_for_display (display, state2);
        xclient.data.l[3] = 0;
        xclient.data.l[4] = 0;
        //gdk_wmspec_change_state( FALSE, window,
        //  gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
        //  GDK_NONE );
        XSendEvent( display,
          //mywin - wrong, not app window, send to root window!
          root, // !! DefaultRootWindow( display ) !!!
          False,
          SubstructureRedirectMask | SubstructureNotifyMask,
          (XEvent *)&xclient );
      }
    
    0 讨论(0)
  • 2020-12-30 18:58

    Use Actual Title Buttons (http://www.actualtools.com/titlebuttons/) for example. It allows to stay any windows always on top , roll up, make transparency and etc..

    0 讨论(0)
  • 2020-12-30 18:59

    I wrote something like this in Xlib many years ago. It's a few lines of code. When your window is partially obscured you get a VisibilityNotify event, then call XRaiseWindow. Watch out for the case where two of your 'always on top' windows overlap.

    0 讨论(0)
  • 2020-12-30 19:06

    You don't want to use XRaiseWindow() to try to stay on top. Some window managers will ignore it entirely. For those that don't, consider what happens if more than one app tries to do this. Boom! That's why the window manager is in charge of stacking windows, not the app.

    The way you do this is to use the protocols defined in the Extended Window Manager Hints (EWMH), see: http://www.freedesktop.org/wiki/Specifications/wm-spec

    Specifically here you want _NET_WM_STATE_ABOVE which is how the "Always on Top" menu item works.

    If you aren't using a toolkit you'll want to get used to scavenging in toolkit source code to figure out how to do things. In this case you could look at the function gdk_window_set_keep_above() in GTK+'s X11 backend. That will show how to use the _NET_WM_STATE_ABOVE hint.

    0 讨论(0)
提交回复
热议问题