https://bugs.kde.org/show_bug.cgi?id=393076

            Bug ID: 393076
           Summary: Oxygen / Window Manager doesn't follow Qt window
                    parent rule in terms of decoration
           Product: Oxygen
           Version: unspecified
          Platform: unspecified
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: hugo.pereira.da.co...@gmail.com
          Reporter: daniel.seb...@ieee.org
  Target Milestone: ---

Created attachment 111984
  --> https://bugs.kde.org/attachment.cgi?id=111984&action=edit
Widget Style & Behavior setting for which Oxygen has no decorations

I'm running Kubuntu (18.x) right now, but the same behavior applies to Mint KDE
and Mageia latest versions.

We,ve been struggling with a bug in the Octave application in which the
reparenting of the Qt window, a QDockWidget, to 0 does not create a top level
window with decorations.  For background, details are here

https://savannah.gnu.org/bugs/?53276

but I think that link discussion is too much to absorb, so I will try to
summarize here.

According to Qt documentation

http://doc.qt.io/qt-5/qwidget.html#details
http://doc.qt.io/qt-5/qwidget.html#top-level-and-child-widgets
http://doc.qt.io/qt-5/qdockwidget.html#setTitleBarWidget

a toplevel window for which

    setParent (0, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
               Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);

or even

    setWindowFlags (Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint
|
                    Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);

should display a full array of decorations, buttons, borders, drag-movement. 
For Oxygen theme, we've found that no decorations appear.  I'll summarize: A
QDockWidget in a docked state that is floated and assigned the above window
attributes is not acquiring window decorations in Oxygen.

One might argue that semantically Qt doesn't exactly say such a thing, but
there is enough inference.  Also, I've tested the above Qt behavior in all the
non-Oxygen KDE frameworks on Kubuntu 18.x and those show decorations nicely. 
To be more specific, I'm attaching a screenshot of the exact KDE setting that
matters,  Widget Style & Behavior.  Furthermore, the decorations rule Qt
describes also works for non-KDE frameworks.

I was perplexed by how this could come about, but having looked at some KDE
code from the git repository, I think I have a better understanding.  Oxygen is
unique in that it, along with the KDE Window Manager, is written in Qt.  The
decorations are written in Qt, the buttons, signals/slots, etc.  All fine.  Of
course, Oxygen / Window Manager can't, say, call member functions associated
with Qt QDockWidget and so on, without being very careful.  So, it looks to me,
where QDockWidget is used by Oxygen, it is more for the sake of settings and
not calling member functions.  Again, all fine, but I'm wondering if those who
developed Oxygen may have not considered the above "rules", because it isn't
obvious that one should check such things when they're in fact using the Qt
framework.  In some sense, Oxygen is rolling its own implementation of Qt,
using Qt, if you follow.

In any case, I've looked around in the source code without identifying exactly
where the problem is, but I have a hunch that I think narrows things down
slightly.  The important parameter in the KDE Window Manager client appears to
be the setting "noborder".  That is, from kwin/client.cp:

bool Client::noBorder() const
{
    return decorationPlugin()->isDisabled() || noborder || isFullScreen();
}

I take it the plugin is enabled (in this case Qxygen), as there are plenty of
elements of the Octave graphical application that have full decorations: dialog
boxes, the main app, etc.  It's not full-screen, but it makes sense that
isFullScreen() appears above.  So "noborder" is it.

Now, noBorder() member function is used in the following routine:

void Client::updateDecoration(bool check_workspace_pos, bool force)
{
    if (!force &&
            ((decoration == NULL && noBorder()) || (decoration != NULL &&
!noBorder())))
        return;
    QRect oldgeom = geometry();
    blockGeometryUpdates(true);
    if (force)
        destroyDecoration();
    if (!noBorder()) {
        createDecoration(oldgeom);
    } else
        destroyDecoration();
    if (check_workspace_pos)
        checkWorkspacePosition(oldgeom);
    updateInputWindow();
    blockGeometryUpdates(false);
    if (!noBorder())
        decoration->show();
    updateFrameExtents();
}

and it is clear if noBorder() is true, then the window decoration->show()
doesn't happen.

Lastly, the following is where "noborder" is set:

void Client::detectNoBorder()
{
    if (shape()) {
        noborder = true;
        app_noborder = true;
        return;
    }
    switch(windowType()) {
    case NET::Desktop :
    case NET::Dock :
    case NET::TopMenu :
    case NET::Splash :
    case NET::Notification :
        noborder = true;
        app_noborder = true;
        break;
    case NET::Unknown :
    case NET::Normal :
    case NET::Toolbar :
    case NET::Menu :
    case NET::Dialog :
    case NET::Utility :
        noborder = false;
        break;
    default:
        abort();
    }
    // NET::Override is some strange beast without clear definition, usually
    // just meaning "noborder", so let's treat it only as such flag, and ignore
it as
    // a window type otherwise (SUPPORTED_WINDOW_TYPES_MASK doesn't include it)
    if (info->windowType(SUPPORTED_MANAGED_WINDOW_TYPES_MASK |
NET::OverrideMask) == NET::Override) {
        noborder = true;
        app_noborder = true;
    }
}

It's pretty clear what the above routine is doing.  Those windows which are
dialogs, menus, normal, etc can have decorations, while things like
splash-screens and notifications can't have decorations.  I suspect the
important entry in the latter category is the NET::Dock.  I'll make a guess
that Oxygen logically sets up a QDockWidget to be in the NET::Dock category and
*perhaps* Oxygen is not setting the class to be something like NET::Normal when
the QDockWidget becomes floated... something along that category I suspect. 
Whereas, the Breeze, Fusion and Windows 9x themes have likely been following
such rules for a long time with legacy KDE Window Manager and Qt-based KDE
Window Manager

Octave is a big program, and probably too much for KDE developers to test, but
if you'd like me to, I could probably use qtcreator to build some simple
QMainWindow application that will immediately float a QDockWidget and turn it
into a top-level window.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to