PhilipRieck / WpfAppBar

WPF AppBar helper
133 stars 48 forks source link

Windows 8.1 multiple taskbar problem #4

Closed mircoboschi closed 3 years ago

mircoboschi commented 9 years ago

Hi, i've encountered problem using this library on win 8.1, docked to top. The first bar is docked correctly, and the desktop size is shrinked without problems. Starting with second bar, stange things happens, including: desktop not shrinking, overlapping bars, smaller bars. The problem is Always reproducible on win 8.1 64; just create an empty window with a "quit" button and launch the same executable from bin/debug multiple times. I was working on a library before finding this (d'oh!) and mine has the same problem, even if seems there are some differences. I've read multiple times msdn article describing desktop appbar development, and all seems ok. ( https://msdn.microsoft.com/en-us/library/windows/desktop/cc144177(v=vs.85).aspx ) Any ideas? have you tried it on 8 / 8.1?

PhilipRieck commented 9 years ago

I haven't tried this scenario at all, but I believe the issue may be larger - multiple problems with multiple bars.

eyaldar commented 9 years ago

The problem stems from ignoring QueryAppBar's suggestion, notice that after executing QueryAppBar the barData's rectangle is changed. Let's take the AppBarExample for example when opened twice(two windows): On the first time you set the appbar everything will execute as expected, but on the second window, your request is changed because you ask the Windows for this placement (on an HD screen): left: 0, bottom: 1080 right: 656, top: 0 which is already occupied by the first window, as a result, when you execute QueryAppBar, barData's rectangle is changed to: left: 656, bottom: 1080 right: 656, top: 0

and because of that, you don't see your window.

in conclusion, to support couple of appbars on the same edge, you should add some recalculation after executing the QueryAppBar method.

eyaldar commented 9 years ago

by the way, you could support multiple screens as well if you don't mind adding System.Drawing and System.Windows.Forms references, it would look something like that: https://github.com/eyaldar/WpfAppBar/commit/752275a89ba42ed3af040349f3298c795e7dc122

mircoboschi commented 9 years ago

PhilipsRieck: Seems to be some weird problem, maybe timing issue? eyaldar: I know that recalculation has to be done. In fact even your code doesn't work correctly, and is exposing same problem as Philips one (and mine too, i've rewritten the helper from scratch multiple times). The strange thing is that windows 8.1 (don't know 8) is behaving somewhat differently from win7. On win7 my code works without problems. I've tried with dock on top and dock on left (as eyealdar example), with same issue: the 2nd bar, and the following one won't resize desktop; also from the 3rd bar on, would also be mis-placed. The issue seems to be only on win 8.1 (8.x?). I've noticed that, on windows 7, the bar placement took ~1 second, on windows 8 is very fast; obviously some underlying change has been done.. Some debug info: First bar is always placed correctly, and desktop is resized accordingly. First queryappbar will return the desired position unchanged, so setappbar would receive correct rect. Second bar is placed correctly, but desktop is not resized. First queryappbar will return the right offset from top (top docking), and bottom should be adjusted accordingly. Setappbar called with an offseted rectangle from top. So, if the desktop won't shrink, seems plausible that setappbar will newly adjust the rectangle, voiding height change.

This is a very strange issue; i've also tried building a winform application, but that's showing the same problem. Obviously, all these tests leads to multiple working appbars on windows 7. Let me know if you need some test code.

eyaldar commented 9 years ago

You are correct, I did miss that it wasn't allocating the appbar. I did notice some weird phenomenon though, if you WINKEY+Right Arrow before changing the edge for the second window it will allocate the required space... In fact, changing the width of the second window will cause it to allocate the space of the delta...

mircoboschi commented 9 years ago

I've already tried that approach yesteday without success (don't have that code with me now, sorry) if we call a second time QueryAppBar, the result rect would be unchanged, telling us that the rectangle is okay. But the behaviour won't change; the SetAppBar would be called with, basically, the same (correct) rectangle, that'll internally corrected to some strange rect value, leading to same synthomps. I've tried disabling hot-corners, hoping in some weird conflict without success. I've also implemented WM_ACTIVATE -> ABM_ACTIVATE and WM_WINDOWPOSCHANGED -> ABM_WINDOWPOSCHANGED event generation as suggested on msdn page; nothing changes.

mircoboschi commented 9 years ago

Poking with multiple app instances, docking and undocking on top edge, i've managed to hang explorer.exe I've windows start bar set to auto-hide on bottom; after some dock-undock of multiple app bar on top, the explorer.exe will hang, along with one or more appbar executable. Killing appbar executables won't unlock exporer! Had to kill explorer.exe and relaunch from task manager. Welcome back to WinXP times :(

PhilipRieck commented 9 years ago

I'll take a look this weekend, but please feel free to send a pull request!

PhilipRieck commented 8 years ago

While trying to test this, it seems the item fixing windows 10 support may have completed it.

Jouni75 commented 8 years ago

Sorry for repeating some points that have already been brought up in this thread by mircoboschi and eyaldar, but here goes:

I have a WPF appbar application built in quite a similar way as this (excellent) example. And I am struggling with Windows 8.x/10 and multiple appbar instances.

The same seems to happen with this example, that when a second instance is docked to the same side where already one instance exists, Windows’ workarea is not reduced accordingly. The result being that the second appbar is now overlapping everything under it, instead of “pushing” windows from under it.

A more specific description about my appbar project can be found here:

http://stackoverflow.com/questions/36640551/an-appbar-application-not-working-correctly-in-windows-8-x-10-desktop-working-a

BTW: I think the latest version of your code is missing a bit of calculating. In ABSetPos function are these lines:

Interop.SHAppBarMessage((int)Interop.ABMsg.ABM_QUERYPOS, ref barData); Interop.SHAppBarMessage((int)Interop.ABMsg.ABM_SETPOS, ref barData);

To my understanding (and as earlier stated by eyaldar), between these lines some re-calculating like this should be done when the appbar is e.g. docked top:

barData.rc.bottom = barData.rc.top + (int)sizeInPixels.Y;

This will make the appbar appear seemingly where it should, but Windows’ workarea is still not reduced.

PhilipRieck: You mentioned that this problem with multiple instances would/might have gone away already. I downloaded the latest version of your example, and the problem seems to still happen at on Win8.1 and Win10.

In your tests multiple instances still work correctly? I was wondering if some Windows patch may have some effects for the good or worse.

Frankly, I think the root problem is due to an internal bug in Windows and SHAppBarMessage, but have not found a confirmation for it.

PS: I am having even bigger problems when my appbar is run via Citrix (even the first instance is not working at all with Win8/10), but I won’t get into that. But if someone has experience about running appbars via Citrix (mainly how to make them work in Win8/10) I’d be glad to hear how. All the required settings have been set in Citrix so that appbars should be supported by it

PhilipRieck commented 8 years ago

@Jouni75 : So testing multiple bars on the same side of the same window does not work as expected.

According to the documentation for ABM_QUERYPOS, the proposed rectangle (and screen edge) should be prefilled, and Windows will adjust the rectangle to ensure it doesn't overlap any other appbars. The SETPOS should then reduce the workarea.

My earlier testing was on win10 RTM, which I no longer have access to for verification. I'm currently up to date with patches on 1511.

Jouni75 commented 8 years ago

Thank you for your swift response, Philip!

Yeah,also to my understanding that is exactly how it should work. And I can see no other reason for the problem than a Window's bug with ABM_SETPOS in Win8.x/10.

I have tested also a WinForms made program, and the same problem occurs. But a colleague of mine tested with (a supposedly native-C made) "7 Sidebar Gadget" (http://nes.bplaced.net/sidebar7.html) on Win8.1, and it did not have this problem. So seems the problem concerns WPF/WinForms applications/windows.

PhilipRieck commented 8 years ago

@Jouni75 I wonder if it's actually a problem with the combination of (and timing between) the WPF resize event and the ABN_POSCHANGED notification that goes out after a window does an ABM_SETPOS.

I'll see if I can find some rhyme or reason. Let me know if you do!

Jouni75 commented 8 years ago

@PhilipRieck Your point about the possible timing issue is a good one. I have tried to get around that by doing the following:

Whenever my app receives an ABN_POSCHANGED in its hooked WndProc, it executes all the appbar positioning code, including ABM_QUERYPOS / ABM_SETPOS -calls.

I also added a SizeChanged event handler for my appbar main window. And if the window has been rendered (window's ContentRendered has been fired), in this SizeChanged handler I again execute all the appbar positioning code.

These cause sometimes a bit of flickering as the appbar moves into its final location. But it also has so far ensured the location is always correct, and that the correct location is also always reduced from Windows Desktop's work area. Until Windows 8.x / 10....

If I find a solution, I will surely let you know!

TonyValenti commented 6 years ago

Hi All, I believe that this issue is caused and resolved by the bug I fixed in #24 .

PhilipRieck commented 3 years ago

With no further comment, I believe release 2.0 or greater has fixed this as the issue is stale. Closing.