OneMore icon indicating copy to clipboard operation
OneMore copied to clipboard

Command Palette blinks the main Window?

Open seaspeak opened this issue 1 year ago • 12 comments

Problem to Solve

Before/After the Command Palette appears/closes, it seems to briefly cause the OneNote main window to disappear, revealing the background behind it. After a brief flicker, the main window returns and the Command Palette dialog is generated.

To Reproduce

Press Ctrl+Shift+P

Expected Behavior

Screenshots

Environment (if applicable)

Version 6.4.0 with OneNote 16.0.14332.20706

Additional Context

seaspeak avatar Jun 04 '24 03:06 seaspeak

I thought it was part of attempting to capture the keyboard ASAP. I have noticed it. Is it just annoying or actually causing you problems?

jasonjac2 avatar Jun 04 '24 08:06 jasonjac2

There is a funky interaction between the windows. Normally, you can set the parent window of a child window and Windows will handle the rest, ensuring the child is shown above the parent. But when setting the OneNote window as the parent, the child windows disappear, and the OneNote window is pushed behind all other windows on your desktop! So OneMore plays a few tricks to set-unset-set the z-order of its windows to ensure they're correctly on top. This sometimes causes things to flicker. If anyone has a cleaner way of doing it, I'd love to hear!

stevencohn avatar Jun 04 '24 11:06 stevencohn

More info for those who think they know the answer LOL... The funky interaction is due to the fact that there is an interop layer in between OneNote and OneMore, via a COM surrogate process. So, the normal parent/child mechanisms don't really work here which is why OneMore takes extraordinary means to force its dialogs to be on top of the OneNote window.

stevencohn avatar Jun 04 '24 12:06 stevencohn

Why is Command Palette particularly noticeably annoying?

seaspeak avatar Jun 04 '24 14:06 seaspeak

I probably need a slower machine :-) I maybe see it once during a session. And it's a very quick flash. Is it happening more often, or every time you open the Command Palette?

stevencohn avatar Jun 04 '24 15:06 stevencohn

I am using Intel 8th gen, got a plan to upgrade to 16th gen if everything goes well :-)

As you said, it is pushed to the bottom of all windows. But isn't the method it used different from SearchHashTags and PreviewMarkdown?

FlickerMoment

Screenshot

Animation

https://github.com/stevencohn/OneMore/assets/8821870/795d2ba1-4bd8-430c-9124-ae6a470f1d07

seaspeak avatar Jun 04 '24 16:06 seaspeak

I'll do some more digging. But to answer your question, no, the Hashtags dialog and the Markdown preview dialog all use different techniques due to their technical requirements.

  • The palette uses System.Window.Forms.Form.ShowDialog() to create a modal dialog.
  • Mardown preview is a wrapper of WebView which needs an STA context.
  • Hashtag uses MoreForm.RunModeless() to create a modeless dialog.

stevencohn avatar Jun 04 '24 16:06 stevencohn

Getting closer, although certainly not perfect. Needed to make concessions around which OneMore windows can be properly TopMost window, meaning the Navigator window can no longer be TopMost??

stevencohn avatar Jul 12 '24 16:07 stevencohn

Thank you for working on this! I have a pretty nice laptop but am consistently seeing the flicker.

Unfortunately, after upgrading to 6.5.0, I still consistently see the flicker, and I'm getting intermittent unresponsiveness from OneNote, not sure if it's related to the command palette or not.

I wonder, is it strictly necessary for the command palette to force itself to appear on top of the OneNote window? For example, if I opened the command palette and then tabbed away to another window, I'd be perfectly happy with the command palette closing itself automatically on focus loss. Would that mean it doesn't need to maintain a parent relationship to the OneNote window?

Another thought: does the flicker go away if the parent/child relationship is established exactly once, and the existing command palette is cached and hidden/shown every time thereafter?

I've never done COM so I don't know if these ideas are at all reasonable.

cspotcode avatar Jul 29 '24 20:07 cspotcode

I was typing up an answer when something occurred to me. I think I may have a solution, but it will mean that the list of commands drop-down that appears by default will be hidden until you start typing. Preliminary testing seems to indicate that this may eliminate the flicker. I'll reopen this. Stay tuned....

stevencohn avatar Jul 29 '24 21:07 stevencohn

Suppressing the drop-down does eliminate the flicker. It will appear immediately once you start typing or press the Down arrow key, so this is a reasonable compromise. Thanks for making me rethink it!

stevencohn avatar Jul 29 '24 21:07 stevencohn

Oh awesome, thanks for taking another look!

cspotcode avatar Jul 30 '24 13:07 cspotcode

I went down a rabbit hole and used AutoHotKey to learn a lot about Win32 GUI.

tl;dr is an "Owner" relationship better than a "Parent" relationship?

AutoHotKey lets me create a GUI window and associate it with the OneNote window. My AutoHotKey script is running as a totally separate process. Is this a sufficient approximation of the COM surrogate relationship between OneNote and OneMore?

AutoHotKey let me try many permutations of: window with Parent relationship, with Owner relationship, with/without ToolWindow, with/without Caption

Setting Owner, nothing else, works best.

Pros

  • No flicker! [^1]
  • Alt-tab treats popup and OneNote as the same window
    • Popup does not pollute alt-tab list
    • When popup has focus, alt-tab believes that OneNote has focus, and will correctly switch to next app. Press Alt-Tab again to switch back. Contrast w/OneMore: alt-tab switches focus between palette and OneNote.
  • They appear/disappear in tandem: minimize, maximize, switch apps, etc.
  • Popup is always on top of OneNote.
  • OneNote window can still receive focus if you click it, e.g. to interact with pages while leaving a search UI open.
  • Popup can be dragged outside the border of the OneNote window, is not confined.

AHK Script

In case it's helpful, here's my AutoHotKey demo.

When it's running, Ctrl+Shift+F in OneNote will show the popup. Escape will close it.

#SingleInstance force

; Ctrl+Shift+F shows popup
#IfWinActive ahk_exe ONENOTE.EXE
^+F:: ShowPopup()
#IfWinActive

; Escape key closes the popup when either popup or OneNote has focus
~Escape::
    Gui, +LastFound
	if WinActive() {
        Gui, Destroy
    }
	if WinActive("ahk_exe ONENOTE.EXE") {
        Gui, Destroy
    }
return

ShowPopup() {
    ; Get HWND of OneNote window
    hParent := WinActive("ahk_exe ONENOTE.exe")
    if !hParent {
        return
    }

    ; Create simple GUI window
    Gui, Font, s12, Bold Verdana
    Gui, Add, Button, x10 y10 Default gButtonTest, Click Me!
    Gui, Add, Text, x10 y50, Sample Text
    Gui, Add, Edit, x10 y80 w200 h100
    Gui, +HWNDhOverlay -MinimizeBox -MaximizeBox

    ; This is the secret! Set +Owner, not +Parent. Caption and ToolWindow optional.
    Gui,                      +Owner%hParent%
    ; Gui, +ToolWindow          +Owner%hParent%
    ; Gui,             -Caption +Owner%hParent%
    ; Gui, +ToolWindow -Caption +Owner%hParent%

    ; Other options, all have problems:
    ; Gui,                      +Owner%hParent% +Parent%hParent%
    ; Gui, +ToolWindow          +Owner%hParent% +Parent%hParent%
    ; Gui,             -Caption +Owner%hParent% +Parent%hParent%
    ; Gui, +ToolWindow -Caption +Owner%hParent% +Parent%hParent%
    ; Gui,                                      +Parent%hParent%
    ; Gui, +ToolWindow                          +Parent%hParent%
    ; Gui,             -Caption                 +Parent%hParent%
    ; Gui, +ToolWindow -Caption                 +Parent%hParent%

    ; PROBLEMS:
    ;    With -Caption:
    ;        No window handle; can't move window.
    ;    Without -Caption:
    ;        Popup window refuses to take focus when clicked. Why?!
    ;    With +Parent:
    ;        Renders behind Ribbon's drop-shadow.  Why?!
    ;        Alt-tab away and back transfers focus from popup to OneNote.
    ;        Popup confined to OneNote window border.

    ; Show GUI popup, focus text input
    ; WinActivate ahk_id %hParent%
    Gui, Show, , Overlay UI
    ControlFocus, Edit1, ahk_id %hOverlay%

    ; Uncomment this to auto-close the popup on focus loss.
    ; while(true) {
    ;     if !WinExist("ahk_id " hOverlay) or (!WinActive("ahk_id " hOverlay) and !WinActive("ahk_id " hParent))
    ;     {
    ;         Reload
    ;     }
    ;     sleep 100
    ; }
}

ButtonTest:
    MsgBox You clicked a button.
Return

[^1]: I still get flicker when closing OneMore's Command Palette.

cspotcode avatar Nov 11 '24 22:11 cspotcode