Updated 2016-09-20 09:07:12 by oehhar
raise window ?aboveThis?

If the aboveThis argument is omitted then the command raises window so that it is above all of its siblings in the stacking order (it will not be obscured by any siblings and will obscure any siblings that overlap it). If aboveThis is specified then it must be the path name of a window that is either a sibling of window or the descendant of a sibling of window. In this case the raise command will insert window into the stacking order just above aboveThis (or the ancestor of aboveThis that is a sibling of window); this could end up either raising or lowering window.

http://www.tcl.tk/man/tcl8.5/TkCmd/raise.htm

  Raising window over other applications on Windows

Program Startup edit

AMGHaO 2016-09-20: On application startup, a "raise ." is sufficient to bring the application above any other application.

Use -topmost edit

HaO 2016-09-20: The -topmost attribute may be set shortly as follows:
focus -force .
raise .
wm attribute . -topmost 1
wm attribute . -topmost 0

The problem of this method is, that the window does not get the input focus. If the user starts typing, it goes in the old application. I normally put buttons on the screen, so the user clicks on them (and implicitly gets the input focus to the application)

Use AllowSetForegroundWindow with cooperative applications edit

The raise command does not work all the time under Win2k. This is a (mis-)feature of Win2k. There is not much Tcl/Tk can do about it.

If your program does not have focus (in other words if your program does not control the Foreground Window) then when you execute the "raise" command, the window you are trying to raise will not go to the very top of the stacking order. The Foreground Window will remain the top-most window.

Depending on what version of windows you have, you might be able to get you window to go to the top by executing "focus -force .". But this does not always work either.

In order to become the top window in stacking order, a window must become the Foreground Window - it must have focus. But this can only be accomplished with the permission of whatever window currently has focus.

Suppose you have two cooperating Tcl programs and you want one program (call it "App1") to be able to signal to another program ("App2") to bring itself to the top. Suppose App1 and App2 are talking to each other over a socket. The App1 can send a message to App2 tell it to raise to the top. But it is not sufficient for App2 to execute just "wm deiconify .; focus -force .; raise .". If that is all that happens, the icon for App2 on the icon bar will flash blue, but the main window for App2 will still be beneath the main window of App1. In order for App2 to raise to the top, App1 must give it permission by calling a special windows API function: AllowSetForegroundWindow(). This routine takes a single argument which is the process ID of App2, or -1 to mean "any process".

Here's an implementation of a TCL command in C that can be used to call this API function:
static int AllowRemoteFocus(TCLARGS){
#ifdef  WIN32

    /* The ASFW_ANY constant is specified in the on-line microsoft documentation
    ** but it does not appear in any header file (that I could find).  The
    ** value was discovered by experimentation.
    */
# ifndef ASFW_ANY
#   define ASFW_ANY -1
# endif

    static HANDLE hu32 = NULL;
    static BOOL (*xAllow)(DWORD) = NULL;
    if( hu32==NULL ){
        hu32 = LoadLibrary("user32");
    }
    if( hu32!=NULL ){
        if( xAllow==NULL ){
            xAllow = GetProcAddress(hu32,"AllowSetForegroundWindow");
        }
        if( xAllow!=NULL ){
            xAllow(ASFW_ANY);
        }
    }
#endif
    return TCL_OK;
}

If you use Tcl_CreateCommand() or Tcl_CreateObjCommand() to register the above function as a TCL command, then App1 can call the command right before sending the message to App2 telling App2 to raise itself. This will allow the "raise" that App2 issues to work. But the call to the command above must occur right before App2 tries to raise itself because the permission to allow other programs to control the focus will expire the next time there is any user input.

The ASFW_ANY macro is defined in the platform SDK version of WinUser.h as
  #define ASFW_ANY ((DWORD)-1)

IIRC the VIsual Studio service packs are for updating the compiler. The Platform SDK is used for updating the operating system link libraries and headers, so it's well worth installing. PT

  Raise to toplevel with MAC-OS


The use of raise on MacOS X is similar to that described for Microsoft Windows above -- i.e. one can modify the sequence of the top-levels of a given application, but not raise them above those of other applications. Happily, Jon Guyer's wizardly Apple events package TclAE comes to the rescue:
 package require tclAE
 tclAE::send -s misc actv

This sends an activate AppleEvent to "self".

Yet another work-around, one that applies equally well to (the affected releases of) Mac OS as well as Windows, shows up in the Mac-Tcl mailing list as a posting [1] by [Adrian Robert].


See also edit