Introduce WindowBeingDraggedWayland

This is just a cleanup. Instead of having WindowBeingDragged
having both code paths, let's keep the non-wayland platforms code
small and clean.
This commit is contained in:
Sergio Martins
2020-10-16 17:00:57 +01:00
parent 059a424b88
commit 171023558e
3 changed files with 107 additions and 55 deletions

View File

@@ -316,7 +316,7 @@ void StateDraggingWayland::onEntry(QEvent *)
}
QScopedValueRollback<bool> guard(m_inQDrag, true);
q->m_windowBeingDragged = std::unique_ptr<WindowBeingDragged>(new WindowBeingDragged(q->m_draggable));
q->m_windowBeingDragged = std::unique_ptr<WindowBeingDragged>(new WindowBeingDraggedWayland(q->m_draggable));
auto mimeData = new WaylandMimeData();
QDrag drag(this);

View File

@@ -76,35 +76,10 @@ WindowBeingDragged::WindowBeingDragged(Draggable *draggable)
, m_draggableWidget(m_draggable->asWidget())
{
if (!isWayland()) {
// Doesn't happen
qWarning() << Q_FUNC_INFO << "This CTOR is only called on Wayland";
qWarning() << Q_FUNC_INFO << "Wrong ctor called."; // Doesn't happen
Q_ASSERT(false);
return;
}
if (auto tb = qobject_cast<TitleBar*>(draggable->asWidget())) {
if (auto fw = tb->floatingWindow()) {
// case #1: we're dragging the whole floating window by its titlebar
m_floatingWindow = fw;
} else if (Frame *frame = tb->frame()) {
m_frame = frame;
} else {
qWarning() << Q_FUNC_INFO <<"Shouldn't happen. TitleBar of what ?";
}
} else if (auto fw = qobject_cast<FloatingWindow*>(draggable->asWidget())) {
// case #2: the floating window itself is the draggable, happens on platforms that support
// native dragging. Not the case for Wayland. But adding this case for completeness.
m_floatingWindow = fw;
#ifdef KDDOCKWIDGETS_QTWIDGETS
} else if (auto tbw = qobject_cast<TabBarWidget*>(draggable->asWidget())) {
m_dockWidget = tbw->currentDockWidget();
} else if (auto tw = qobject_cast<TabWidgetWidget*>(draggable->asWidget())) {
m_frame = tw->frame();
#endif
} else {
qWarning() << "Unknown draggable" << draggable->asWidget()
<< "please fix";
}
}
#if DOCKS_DEVELOPER_MODE
@@ -159,10 +134,6 @@ QSize WindowBeingDragged::size() const
{
if (m_floatingWindow)
return m_floatingWindow->size();
else if (m_frame)
return m_frame->QWidgetAdapter::size();
else if (m_dockWidget)
return m_dockWidget->size();
return QSize();
}
@@ -172,10 +143,6 @@ QSize WindowBeingDragged::minSize() const
if (m_floatingWindow) {
Layouting::ItemContainer *root = m_floatingWindow->dropArea()->rootItem();
return root->minSize();
} else if (m_frame) {
return m_frame->minSize();
} else if (m_dockWidget) {
return Layouting::Widget::widgetMinSize(m_dockWidget.data());
}
return {};
@@ -186,10 +153,6 @@ QSize WindowBeingDragged::maxSize() const
if (m_floatingWindow) {
Layouting::ItemContainer *root = m_floatingWindow->dropArea()->rootItem();
return root->maxSizeHint();
} else if (m_frame) {
return m_frame->maxSizeHint();
} else if (m_dockWidget) {
return Layouting::Widget::widgetMaxSize(m_dockWidget.data());
}
return {};
@@ -203,7 +166,51 @@ bool WindowBeingDragged::contains(DropArea *dropArea) const
return m_floatingWindow && m_floatingWindow->dropArea() == dropArea;
}
QPixmap WindowBeingDragged::pixmap() const
Draggable *WindowBeingDragged::draggable() const
{
return m_draggable;
}
WindowBeingDraggedWayland::WindowBeingDraggedWayland(Draggable *draggable)
: WindowBeingDragged(draggable)
{
if (!isWayland()) {
// Doesn't happen
qWarning() << Q_FUNC_INFO << "This CTOR is only called on Wayland";
Q_ASSERT(false);
return;
}
if (auto tb = qobject_cast<TitleBar*>(draggable->asWidget())) {
if (auto fw = tb->floatingWindow()) {
// case #1: we're dragging the whole floating window by its titlebar
m_floatingWindow = fw;
} else if (Frame *frame = tb->frame()) {
m_frame = frame;
} else {
qWarning() << Q_FUNC_INFO <<"Shouldn't happen. TitleBar of what ?";
}
} else if (auto fw = qobject_cast<FloatingWindow*>(draggable->asWidget())) {
// case #2: the floating window itself is the draggable, happens on platforms that support
// native dragging. Not the case for Wayland. But adding this case for completeness.
m_floatingWindow = fw;
#ifdef KDDOCKWIDGETS_QTWIDGETS
} else if (auto tbw = qobject_cast<TabBarWidget*>(draggable->asWidget())) {
m_dockWidget = tbw->currentDockWidget();
} else if (auto tw = qobject_cast<TabWidgetWidget*>(draggable->asWidget())) {
m_frame = tw->frame();
#endif
} else {
qWarning() << "Unknown draggable" << draggable->asWidget()
<< "please fix";
}
}
WindowBeingDraggedWayland::~WindowBeingDraggedWayland()
{
}
QPixmap WindowBeingDraggedWayland::pixmap() const
{
QPixmap pixmap(size());
QPainter p(&pixmap);
@@ -220,7 +227,43 @@ QPixmap WindowBeingDragged::pixmap() const
return pixmap;
}
Draggable *WindowBeingDragged::draggable() const
QSize WindowBeingDraggedWayland::size() const
{
return m_draggable;
if (m_floatingWindow)
return WindowBeingDragged::size();
else if (m_frame)
return m_frame->QWidgetAdapter::size();
else if (m_dockWidget)
return m_dockWidget->size();
qWarning() << Q_FUNC_INFO << "Unknown size, shouldn't happen";
return QSize();
}
QSize WindowBeingDraggedWayland::minSize() const
{
if (m_floatingWindow) {
return WindowBeingDragged::minSize();
} else if (m_frame) {
return m_frame->minSize();
} else if (m_dockWidget) {
return Layouting::Widget::widgetMinSize(m_dockWidget.data());
}
qWarning() << Q_FUNC_INFO << "Unknown minSize, shouldn't happen";
return {};
}
QSize WindowBeingDraggedWayland::maxSize() const
{
if (m_floatingWindow) {
return WindowBeingDragged::maxSize();
} else if (m_frame) {
return m_frame->maxSizeHint();
} else if (m_dockWidget) {
return Layouting::Widget::widgetMaxSize(m_dockWidget.data());
}
qWarning() << Q_FUNC_INFO << "Unknown maxSize, shouldn't happen";
return {};
}

View File

@@ -32,16 +32,12 @@ struct DOCKS_EXPORT_FOR_UNIT_TESTS WindowBeingDragged
public:
explicit WindowBeingDragged(FloatingWindow *fw, Draggable *draggable);
///@brief Constructor for Wayland only, where we aren't dragging a FloatingWindow
/// bue faking it with a QDrag+pixmap
explicit WindowBeingDragged(Draggable *draggable);
#if DOCKS_DEVELOPER_MODE
// For tests.
explicit WindowBeingDragged(FloatingWindow *fw);
#endif
~WindowBeingDragged();
virtual ~WindowBeingDragged();
void init();
FloatingWindow *floatingWindow() const { return m_floatingWindow; }
@@ -53,38 +49,51 @@ public:
QStringList affinities() const;
///@brief size of the window being dragged contents
QSize size() const;
virtual QSize size() const;
/// @brief returns the min-size of the window being dragged contents
QSize minSize() const;
virtual QSize minSize() const;
/// @brief returns the max-size of the window being dragged contents
QSize maxSize() const;
virtual QSize maxSize() const;
/// @brief returns whether the window being dragged contains the specified drop area
/// useful since we don't want to drop onto outselves.
bool contains(DropArea *) const;
/// @brief Returns a pixmap representing this Window. For purposes of QDrag
/// For wayland only
QPixmap pixmap() const;
/// @brief Returns a pixmap representing this Window. For purposes of QDrag. Wayland only.
virtual QPixmap pixmap() const { return {}; }
/// @brief Returns the draggable
Draggable *draggable() const;
private:
protected:
explicit WindowBeingDragged(Draggable *);
Q_DISABLE_COPY(WindowBeingDragged)
QPointer<FloatingWindow> m_floatingWindow;
Draggable *const m_draggable;
QPointer<QWidgetOrQuick> m_draggableWidget; // Just to have a QPointer on it
const QStringList m_affinities;
};
struct WindowBeingDraggedWayland : public WindowBeingDragged
{
public:
explicit WindowBeingDraggedWayland(Draggable *draggable);
~WindowBeingDraggedWayland() override;
// These two are set for Wayland only, where we can't make the floating window immediately (no way to position it)
// So we're dragging either a frame with multiple dock widgets or a single tab, keep them here.
// It's important to know what we're dragging, so drop rubber band respect min/max sizes.
QPointer<Frame> m_frame;
QPointer<DockWidgetBase> m_dockWidget;
const QStringList m_affinities;
QSize size() const override;
QSize minSize() const override;
QSize maxSize() const override;
QPixmap pixmap() const override;
};
}
#endif