Finished implementing maximize for linux.

Added FloatingContainerForc*TitleBar to switch between native and custom titlebar.

Co-authored-by: SleepProgger <SleepProgger@users.noreply.github.com>
This commit is contained in:
helywin
2019-09-12 10:44:12 +08:00
committed by Some Guy
parent 48fb999bd0
commit 533d174abc
10 changed files with 533 additions and 37 deletions

View File

@@ -376,6 +376,7 @@ struct FloatingDockContainerPrivate
#ifdef Q_OS_LINUX
QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr;
bool IsResizing = false;
#endif
/**
@@ -410,10 +411,11 @@ struct FloatingDockContainerPrivate
void setWindowTitle(const QString &Text)
{
#ifdef Q_OS_LINUX
TitleBar->setTitle(Text);
#else
_this->setWindowTitle(Text);
if(TitleBar){
TitleBar->setTitle(Text);
}
#endif
_this->setWindowTitle(Text);
}
/**
@@ -604,13 +606,36 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
SLOT(onDockAreasAddedOrRemoved()));
#ifdef Q_OS_LINUX
d->TitleBar = new CFloatingWidgetTitleBar(this);
setWindowFlags(windowFlags() | Qt::Tool);
QDockWidget::setWidget(d->DockContainer);
QDockWidget::setFloating(true);
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
setTitleBarWidget(d->TitleBar);
connect(d->TitleBar, SIGNAL(closeRequested()), SLOT(close()));
QDockWidget::setWidget(d->DockContainer);
QDockWidget::setFloating(true);
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
// KDE doesn't seem to fire MoveEvents while moving windows, so for now no native titlebar for everything using KWin.
QString window_manager = internal::windowManager().toUpper().split(" ")[0];
bool native_window = window_manager != "KWIN";
// FloatingContainerForce*TitleBar is overwritten by the "ADS_UseNativeTitle" environment variable if set.
auto env = qgetenv("ADS_UseNativeTitle").toUpper();
if (env == "1"){
native_window = true;
} else if (env == "0"){
native_window = false;
} else if ( DockManager->testConfigFlag( CDockManager::FloatingContainerForceNativeTitleBar )){
native_window = true;
} else if ( DockManager->testConfigFlag( CDockManager::FloatingContainerForceCustomTitleBar )){
native_window = false;
}
if(native_window){
setTitleBarWidget(new QWidget());
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
} else {
d->TitleBar = new CFloatingWidgetTitleBar(this);
setTitleBarWidget(d->TitleBar);
setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint);
d->TitleBar->enableCloseButton(isClosable());
connect(d->TitleBar, SIGNAL(closeRequested()), SLOT(close()));
connect(d->TitleBar, &CFloatingWidgetTitleBar::maximizeRequested,
this, &CFloatingDockContainer::onMaximizeRequest);
}
#else
setWindowFlags(
Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
@@ -629,9 +654,7 @@ CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget *DockArea) :
CFloatingDockContainer(DockArea->dockManager())
{
d->DockContainer->addDockArea(DockArea);
#ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable());
#endif
auto TopLevelDockWidget = topLevelDockWidget();
if (TopLevelDockWidget)
{
@@ -646,9 +669,6 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget *DockWidget) :
CFloatingDockContainer(DockWidget->dockManager())
{
d->DockContainer->addDockWidget(CenterDockWidgetArea, DockWidget);
#ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable());
#endif
auto TopLevelDockWidget = topLevelDockWidget();
if (TopLevelDockWidget)
{
@@ -678,12 +698,18 @@ CDockContainerWidget* CFloatingDockContainer::dockContainer() const
//============================================================================
void CFloatingDockContainer::changeEvent(QEvent *event)
{
QWidget::changeEvent(event);
Super::changeEvent(event);
if ((event->type() == QEvent::ActivationChange) && isActiveWindow())
{
ADS_PRINT("FloatingWidget::changeEvent QEvent::ActivationChange ");
d->zOrderIndex = ++zOrderCounter;
return;
#ifdef Q_OS_LINUX
if(d->DraggingState == DraggingFloatingWidget){
d->titleMouseReleaseEvent();
d->DraggingState = DraggingInactive;
}
#endif
}
}
@@ -825,13 +851,19 @@ void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
#ifndef Q_OS_LINUX
Q_UNUSED(MouseEventHandler)
#endif
#ifdef Q_OS_LINUX
if (!isMaximized()) {
resize(Size);
d->DragStartMousePosition = DragStartMousePos;
}
#else
resize(Size);
d->setState(DragState);
d->DragStartMousePosition = DragStartMousePos;
#endif
d->setState(DragState);
#ifdef Q_OS_LINUX
if (DraggingFloatingWidget == DragState)
{
setAttribute(Qt::WA_X11NetWmWindowTypeDock, true);
d->MouseEventHandler = MouseEventHandler;
if (d->MouseEventHandler)
{
@@ -839,7 +871,13 @@ void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
}
}
#endif
#ifdef Q_OS_LINUX
if (!isMaximized()) {
moveFloating();
}
#else
moveFloating();
#endif
show();
}
@@ -850,7 +888,6 @@ void CFloatingDockContainer::moveFloating()
const QPoint moveToPos = QCursor::pos() - d->DragStartMousePosition
- QPoint(BorderSize, 0);
move(moveToPos);
switch (d->DraggingState)
{
case DraggingMousePressed:
@@ -949,11 +986,16 @@ bool CFloatingDockContainer::restoreState(CDockingStateReader &Stream,
{
return false;
}
onDockAreasAddedOrRemoved();
#ifdef Q_OS_LINUX
if(d->TitleBar){
d->TitleBar->setMaximizedIcon(windowState() == Qt::WindowMaximized);
}
#endif
return true;
}
//============================================================================
bool CFloatingDockContainer::hasTopLevelDockWidget() const
{
@@ -977,19 +1019,17 @@ void CFloatingDockContainer::finishDragging()
{
ADS_PRINT("CFloatingDockContainer::finishDragging");
#ifdef Q_OS_LINUX
setAttribute(Qt::WA_X11NetWmWindowTypeDock, false);
setWindowOpacity(1);
activateWindow();
if (d->MouseEventHandler)
{
d->MouseEventHandler->releaseMouse();
d->MouseEventHandler = nullptr;
}
setWindowOpacity(1);
activateWindow();
if (d->MouseEventHandler)
{
d->MouseEventHandler->releaseMouse();
d->MouseEventHandler = nullptr;
}
#endif
d->titleMouseReleaseEvent();
d->titleMouseReleaseEvent();
}
#ifdef Q_OS_MACOS
//============================================================================
bool CFloatingDockContainer::event(QEvent *e)
@@ -1092,6 +1132,71 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
}
#endif
#ifdef Q_OS_LINUX
void CFloatingDockContainer::onMaximizeRequest()
{
if(windowState() == Qt::WindowMaximized){
showNormal();
}else{
showMaximized();
}
}
void CFloatingDockContainer::showNormal(bool fixGeometry)
{
if (windowState() == Qt::WindowMaximized)
{
QRect oldNormal = normalGeometry();
Super::showNormal();
if(fixGeometry)
{
setGeometry(oldNormal);
}
}
if(d->TitleBar){
d->TitleBar->setMaximizedIcon(false);
}
}
void CFloatingDockContainer::showMaximized()
{
Super::showMaximized();
if(d->TitleBar){
d->TitleBar->setMaximizedIcon(true);
}
}
bool CFloatingDockContainer::isMaximized() const
{
return windowState() == Qt::WindowMaximized;
}
void CFloatingDockContainer::show(){
// Prevent this window from showing in the taskbar and pager (alt+tab)
internal::xcb_add_prop(true, winId(), "_NET_WM_STATE", "_NET_WM_STATE_SKIP_TASKBAR");
internal::xcb_add_prop(true, winId(), "_NET_WM_STATE", "_NET_WM_STATE_SKIP_PAGER");
Super::show();
}
void CFloatingDockContainer::resizeEvent(QResizeEvent *event){
d->IsResizing = true;
Super::resizeEvent(event);
}
void CFloatingDockContainer::moveEvent(QMoveEvent *event){
Super::moveEvent(event);
if(!d->IsResizing && event->spontaneous()){
d->DraggingState = DraggingFloatingWidget;
d->updateDropOverlays(QCursor::pos());
}
d->IsResizing = false;
}
bool CFloatingDockContainer::hasNativeTitleBar(){
return d->TitleBar == nullptr;
}
#endif
} // namespace ads
//---------------------------------------------------------------------------