mosg
mosg

Reputation: 12391

HowTo stick QDialog to Screen Borders like Skype do?

A long time ago I tried to find method how to stick QDialog window to screen borders for my small projects like Skype windows do it, but I failed. May be I was looking this code not in the right place, so now I'm looking the solution here, on stack! :)

So, does any one have a deal with some kind of such code, links, samples?

In my opinion, we have to reimplement QDialog moveEvent function, like below, but that code does not working:

void    CDialog::moveEvent(QMoveEvent * event) {

    QRect wndRect;
    int leftTaskbar = 0, rightTaskbar = 0, topTaskbar = 0, bottomTaskbar = 0;
//  int top = 0, left = 0, right = 0, bottom = 0;

    wndRect = this->frameGeometry();

    // Screen resolution
    int screenWidth =   QApplication::desktop()->width();
    int screenHeight =  QApplication::desktop()->height();

    int wndWidth = wndRect.right() - wndRect.left();
    int wndHeight = wndRect.bottom() - wndRect.top();

    int posX = event->pos().x();
    int posY = event->pos().y();

    // Snap to screen border
    // Left border
    if (posX >= -m_nXOffset + leftTaskbar &&
        posX <= leftTaskbar + m_nXOffset) {
        //left = leftTaskbar;
        this->move(leftTaskbar, posY);
        return;
    }

    // Top border
    if (posY >= -m_nYOffset &&
        posY <= topTaskbar + m_nYOffset) {
        //top = topTaskbar;
        this->move(posX, topTaskbar);
        return;
    }

    // Right border
    if (posX + wndWidth <= screenWidth - rightTaskbar + m_nXOffset &&
        posX + wndWidth >= screenWidth - rightTaskbar - m_nXOffset) {
        //right = screenWidth - rightTaskbar - wndWidth;
        this->move(screenWidth - rightTaskbar - wndWidth, posY);
        return;
    }

    // Bottom border
    if (posY + wndHeight <= screenHeight - bottomTaskbar + m_nYOffset &&
        posY + wndHeight >= screenHeight - bottomTaskbar - m_nYOffset) {
        //bottom = screenHeight - bottomTaskbar - wndHeight;
        this->move(posX, screenHeight - bottomTaskbar - wndHeight);
        return;
    }

    QDialog::moveEvent(event);
}

Thanks.

Upvotes: 3

Views: 2331

Answers (2)

Lohrun
Lohrun

Reputation: 6772

In the pos property description from the QWidget documentation, there is the following warning about moving a window inside the move event handling method.

Warning: Calling move() or setGeometry() inside moveEvent() can lead to infinite recursion.

That said, there is no proper way to stick the dialog window inside the screen border.

Note : The behavior you observed in KDE comes from the Window Manager. Actually, the Window Manager is the one that arranges the application windows (like dialog boxes) to show them on the screen. The KDE Window Manager has an option to make all application windows (called client) stick to the border.

Upvotes: 1

Patrice Bernassola
Patrice Bernassola

Reputation: 14436

As you thought you can achieve this in the moveEvent function. I guess the following code do the trick but since I have nothing to test here I will write some pseudo code:

First get the available screen area:

const QRect screen = QApplication::availableGeometry(this);
// This get the screen rect where you can drag a dialog

Then get the position of your dialog relative to the desktop (if your dialog is a child of an other widget, you need to transform coordinates from widget relative to desktop relative):

const QRect dialog = geometry();
// Do here transformation

Now test if dialog is near screen border

if( abs(dialog.left()-screen.left() < OFFSET )
    move(screen.left(), dialog.top();
else if( abs(dialog.top()-screen.top() < OFFSET )
    move(dialog.left(), screen.top() )
// etc. for the 2 other cases

Let me know if it works

Upvotes: 1

Related Questions