stevencohn / OneMore

A OneNote add-in with simple, yet powerful and useful features
Mozilla Public License 2.0
2.66k stars 223 forks source link

Command Palette blinks the main Window? #1422

Open seaspeak opened 5 months ago

seaspeak commented 5 months ago

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

jasonjac2 commented 5 months ago

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?

stevencohn commented 5 months ago

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 commented 5 months ago

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.

seaspeak commented 5 months ago

Why is Command Palette particularly noticeably annoying?

stevencohn commented 5 months ago

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?

seaspeak commented 5 months ago

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

stevencohn commented 5 months ago

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.

stevencohn commented 4 months ago

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??

cspotcode commented 4 months ago

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.

stevencohn commented 4 months ago

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 commented 4 months ago

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!

cspotcode commented 4 months ago

Oh awesome, thanks for taking another look!

cspotcode commented 2 weeks ago

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

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.