Autoraise panel windows

Dear all,

Is there a good way to autoraise panel windows upon mouseover, or I should write my own?

DoWindow/F in a simple named window hook function (run command displayhelptopics "named window hook functions" for info) works nicely. In the hook function, the name of the window calling the function can be checked against the order of windows provided by the WinList function to see if the call to DoWindow/F is needed. The one limitation I've noticed is that the command line window appears to be invisible to the WinList and WinName* functions, so if the window is to be brought even in front of the command line on mouse over, DoWindow/F has to be called whenever mouse over occurs.

I haven't come across a more built-in way to do this, but I haven't looked exhaustively.

*Side note: WinName seems to return a narrower set of window types than does WinList. For example, WinName appears unable to return the names of help windows (e.g., "Advanced Topics.ihf").
aoa wrote:
DoWindow/F in a simple named window hook function (run command displayhelptopics "named window hook functions" for info) works nicely. In the hook function, the name of the window calling the function can be checked against the order of windows provided by the WinList function to see if the call to DoWindow/F is needed. The one limitation I've noticed is that the command line window appears to be invisible to the WinList and WinName* functions, so if the window is to be brought even in front of the command line on mouse over, DoWindow/F has to be called whenever mouse over occurs.

I haven't come across a more built-in way to do this, but I haven't looked exhaustively.


Yeah, I haven't come upon a built-in setting either.

aoa wrote:
*Side note: WinList seems to return a narrower set of window types than does WinList. For example, WinName appears unable to return the names of help windows (e.g., "Advanced Topics.ihf").


You mean WinName returns a narrower set than WinList

If I come-up with a solution I will post it as a code snippet.

best,
_sk
_sk wrote:
You mean WinName returns a narrower set than WinList


Indeed I did mean that. I'll edit my original post to avoid confusion. Thanks for pointing that out.
aoa wrote:

*Side note: WinName seems to return a narrower set of window types than does WinList. For example, WinName appears unable to return the names of help windows (e.g., "Advanced Topics.ihf").

Help and procedure windows don't actually have names, only titles. WinList has the following note regarding this detail:
"Procedure windows and help windows don't have names. WinList returns the window title instead."
Okay so this is the quick hack I came up with: autoraising panels and graphs. Modify as you wish.

Note: if you have hooks on mousemoved event, find a different event that works. For example, I lump the hooks which do all the real work in a modified event, so these two events don't clash.

Edit: updated the code.

menu "Misc", dynamic
    "--"
    ugsk_autoraise_menu_title(), /Q, ugsk_autoraise_toggle()
    help={"Auto-raise panels and graphs on hover"}
end

function/s ugsk_autoraise_menu_title()
   
    nvar/z v_chk = root:autoraise:ui:v_chk
    if (!nvar_exists(v_chk))
        newdatafolder/o root:autoraise
        newdatafolder/o root:autoraise:ui
        variable/g root:autoraise:ui:v_chk = 0
        return "Autoraise: is off"
    elseif (v_chk == 0)
        return "Autoraise: is off"
    else
        return "Autoraise: is on"
    endif
end

function ugsk_autoraise_toggle()
    nvar/z v_chk = root:autoraise:ui:v_chk
    if (v_chk == 1)
        v_chk = 0
        ugsk_autoraise_hook_kill()
        return 0
    else
        v_chk = 1
        ugsk_autoraise_hook_install()
    endif
end

function ugsk_autoraise_hook_kill()
    string s_win = ""
    string s_winlist = winlist("*",";","WIN:65,VISIBLE:1")
    variable v_win = itemsinlist(s_winlist)
    variable i = 0
    string s_hook = ""
    for ( i=0; i<v_win; i+=1 )
        s_win = stringfromlist(i, s_winlist, ";")
           
        setwindow $s_win hook(mousemoved)=$""
               
    endfor
end

function ugsk_autoraise_hook_install()
    string s_win = ""
    string s_winlist = winlist("*",";","WIN:65,VISIBLE:1")
    variable v_win = itemsinlist(s_winlist)
    variable i = 0
    string s_hook = ""
    for ( i=0; i<v_win; i+=1 )
        s_win = stringfromlist(i, s_winlist, ";")
           
        setwindow $s_win hook(mousemoved)=ugsk_autoraise_raise
               
    endfor
end


function ugsk_autoraise_raise(s)
   
    STRUCT WMWinHookStruct &s
   
    if (s.eventcode == 4)
        dowindow/F $(s.winname)
        return 0
    endif
end


best,
_sk
OK, I'm glad you figured that out.

But I'm curious- this doesn't actually seem like a good idea to me. Every time the mouse happens to pass over a window it pops to the front? It's so easy to stray over territory you didn't intend that I would expect windows to be constantly popping forward.

Please enlighten me!

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
OK, I'm glad you figured that out.

But I'm curious- this doesn't actually seem like a good idea to me. Every time the mouse happens to pass over a window it pops to the front? It's so easy to stray over territory you didn't intend that I would expect windows to be constantly popping forward.

Please enlighten me!

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com


When a panel has to be always on top, the only way to achieve this is with a floating panel (i.e. /FLT=1). So if you click (mousedown, mouseup) a control in a floating panel, the panel bubbles the event to the control, the control does whatever and transfers back to the panel, and the panel transfers the focus to the the previous panel. But a floating panel does not hook into mousewheel events. As a result if you have a setvariable control you cannot spin a setvariable control with a mousewheel when the panel is floating.

So, is this (to not intercept mousewheel events) a bug or a feature in the floating panel implementation?

Even if the panel is not instantiated as floating, the user still needs to raise the panel (i.e. the panel to acquire focus) and only then can the panel receive events, which makes sense in most cases. But in some cases, small modular panels can provide functionality without being embedded in a bigger panel or graph; thus my usecase, and thus my code.

best,
_sk
I agree with John, particularly if you apply the hook to all open graph & panel windows and there are a lot open. How about a menu item to just add/remove the hook to/from the top graph or panel along with an option to apply to all?
jtigor wrote:
I agree with John, particularly if you apply the hook to all open graph & panel windows and there are a lot open. How about a menu item to just add/remove the hook to/from the top graph or panel along with an option to apply to all?


By all means modify it as you see fit. The code belongs to the community.

best,
_sk
OK, I see your point about floating panels. I would say that's a bug. I'll add it to my queue.

The present behavior of controls and the mouse wheel is an attempt to make our controls behave more like (my perhaps imperfect knowledge of) Windows behavior. In general, on Windows, you have to focus a window or panel in a window in order to get mouse wheel events. But I also note that after putting a lot of effort into that, I found that Windows 10 makes that behavior optional. Still work to be done...

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com