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:
@@ -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);
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user