Bug 366278 - Application menu items hidden behind auto-hide taskbar
Summary: Application menu items hidden behind auto-hide taskbar
Status: RESOLVED FIXED
Alias: None
Product: plasmashell
Classification: Plasma
Component: Application Menu (Kicker) (show other bugs)
Version: 5.7.1
Platform: Fedora RPMs Linux
: NOR normal
Target Milestone: 1.0
Assignee: Eike Hein
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-07-30 14:32 UTC by Martin Vuille
Modified: 2016-08-02 10:20 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Screen capture showing problem (1.27 MB, image/png)
2016-07-30 14:38 UTC, Martin Vuille
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Vuille 2016-07-30 14:32:30 UTC
I have panel with taskbar, launcher, etc. configured as auto-hide
I am using the "Application Menu" launcher (cascading menus)
When a submenu is displayed, it can sometimes extend behind the taskbar, making some items in that submenu inaccessible


Reproducible: Always

Steps to Reproduce:
1. Configure per above description
2. Open menu, select menu item near the bottom that has many subitems 

Actual Results:  
Bottom subitems are hidden behind taskbar


Expected Results:  
Submenu is drawn above or in front of the taskbar
Comment 1 Martin Vuille 2016-07-30 14:38:05 UTC
Created attachment 100390 [details]
Screen capture showing problem
Comment 2 Eike Hein 2016-07-30 15:57:52 UTC
Some sort of strut problem, Martin?
Comment 3 Martin Vuille 2016-07-30 16:50:29 UTC
Unfortunately I am very new to Qt/KDE/Plasma internals and not familiar with the term "strut".
Light Googling suggests it means a "keep out" area?

I would say that it's a Z-order issue rather than a "keep out" issue. Consider a case where I have a full-screen application minimized to the task bar. If I unhide the taskbar and restore the application, I would like it to use the entire desktop, including the area behind the taskbar. So, in that regard, the taskbar should not be considered a "keep out" area.

FWIW, on Windows (where I also have an auto-hide taskbar and I'm using Classic Start Menu to emulate Win2K cascading menus,) the submenus are displayed in front of the taskbar.
Comment 4 Eike Hein 2016-07-30 17:02:40 UTC
Oh, sorry about the confusion - I was asking the Martin I added to the CC list for technical input :)
Comment 5 Martin Flöser 2016-08-01 07:04:49 UTC
(In reply to Eike Hein from comment #2)
> Some sort of strut problem, Martin?

IIRC auto-hiding panels don't set struts. This rather looks like an incorrect transient problem to me. The sub-menu should be a transient to the main menu, which should be a transient to the panel. If that's all setup correctly the windows should all be in the same layer and above the panel.
Comment 6 Eike Hein 2016-08-01 08:36:34 UTC
^ Thanks!
Comment 7 Eike Hein 2016-08-02 10:20:54 UTC
Git commit 433b6794fe8c08fee91dd8d307604ae0207d14c5 by Eike Hein.
Committed on 02/08/2016 at 10:20.
Pushed by hein into branch 'master'.

Add Qt::Dialog to default flags to make QXcbWindow::isTransient() happy.

Panel popup dialogs along with other applications of Plasma::Dialog
(e.g. Kicker's submenus) currently don't correctly set WM_TRANSIENT_FOR
to the id of their parent window on X11. This causes them to interact
badly with auto-hide panels which do not set struts, e.g. Kicker's
submenus open behind the panel.

Internally, Dialog makes calls to QWindow::setFlags when its window
type is "Normal" (the default) and otherwise uses KWindowSystem's
setType. (Kicker's subclass, SubMenu, does an additional
KWindowSystem::setType call for NET::Menu). Neither CompactApplet
nor Kicker change their Dialog's 'type' property to anything else,
so their dialogs are "Normal", thus going the setFlags route with
no setType calls.

Dialog also sets its transient parent to the window the visualParent
item is inside of.

Now here is where things break down: QXcbWindow will update
WM_TRANSIENT_PARENT for in show(), but only when an inline function
called isTransient returns true. isTransient decides this based on
window type, which is determined from the flags set with
QWindow::setFlags. Calls to KWindowSystem::setType would have no
bearing on this; there seems to be no mapping back from external
state. This is why setting Dialog.type to e.g. "DialogWindow" does
nothing.

This patch takes the route of adding Qt::Dialog to the starting
flags - after all Dialog is a dialog. That means isTransient()
will consider the window to be a transient and those
setTransientParent calls Dialog does will not be ignored. In the
case of CompactApplet, no further calls to KWS::setType are done;
Kicker continues to call it with NET::Menu to get desired window
manager behavior.

In light testing everything still seems too work, with the added
benefit of fixing:

That said, the weird mess of setFlags and setType and state in the
windowing system vs. Qt is horrible and sad.

REVIEW:128571

M  +1    -1    src/plasmaquick/dialog.cpp

http://commits.kde.org/plasma-framework/433b6794fe8c08fee91dd8d307604ae0207d14c5