How to RaiseWindow() on a TApplication?

I have a small TApplication-derived gui program that I want to ensure it’s window remains on top.
I’d like to call the TCanvas::RaiseWindow() on a 1 second timer, but I can’t figure out how to find the canvas for my TApplication.

How can I force this application’s window to the top?
Do TApplication’s with only gui widgets (TG…) have a canvas?

This is with Root 5.26 on linux, uxing X11.

thanks very much for your help
buddy

Hi buddy,

You can access the list of canvases via gROOT->GetListOfCanvases();
For example:

((TCanvas*)gROOT->GetListOfCanvases()->FindObject("c1"))->RaiseWindow();

It is very Window Manager dependent, and there is nothing in ROOT to force a Window to stay on top…
Here is an example of what could be done (but it may not work…):

//______________________________________________________________________________
void MyWindow::SetAlwaysOnTop(Bool_t set)
{
   // Alter the status of the windows to keep it always on top of other windows.

#ifdef WIN32
   HWND window = (HWND)GDK_DRAWABLE_XID((GdkWindow *)GetId());
   if (set)
      SetWindowPos(window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE |
                   SWP_NOMOVE | SWP_NOSIZE);
   else
      SetWindowPos(window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE |
                   SWP_NOMOVE | SWP_NOSIZE);
#else
   Display *disp = (Display*)gVirtualX->GetDisplay();
   XEvent ev;
   memset(&ev, 0, sizeof(ev));
   ev.type=ClientMessage;
   ev.xclient.type         = ClientMessage;
   ev.xclient.message_type = XInternAtom(disp, "_NET_WM_STATE", 0);
   ev.xclient.display      = disp;
   ev.xclient.window       = fId;
   ev.xclient.format       = 32;
   ev.xclient.data.l[0]    = set ? 1 : 0;
   // *_STAYS_ON_TOP is probably KDE-specific
   ev.xclient.data.l[1] = XInternAtom(disp, "_NET_WM_STATE_STAYS_ON_TOP", 0);
   XLockDisplay(disp);
   XSendEvent(disp, XDefaultRootWindow(disp), 0, SubstructureRedirectMask |
              SubstructureNotifyMask, &ev);
   // to work with some non-KDE WMs we should use _NET_WM_STATE_ABOVE
   ev.xclient.data.l[1] = XInternAtom(disp, "_NET_WM_STATE_ABOVE", 0);
   XSendEvent(disp, XDefaultRootWindow(disp), 0, SubstructureRedirectMask |
              SubstructureNotifyMask, &ev);
   XUnlockDisplay(disp);
#endif
}

Well, they can, it depends if you create one (or more)…

Cheers, Bertrand.

Thanks for that code, Bertrand. It works very nice in a real linux X environment.

FYI, as you supposed, it doesn’t work when running an xterm window from a microsoft windows system (either XMinG or starnet).

thanks,
buddy

Hi buddy,

Youre welcome! Glad to know it was useful! And yes, this is one of the problems when going to very WM specific operations…

Cheers, Bertrand.