source: trunk/src/gui/kernel/qwidget_qws.cpp@ 642

Last change on this file since 642 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 37.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qcursor.h"
43#include "qapplication.h"
44#include "qapplication_p.h"
45#include "qpainter.h"
46#include "qbitmap.h"
47#include "qimage.h"
48#include "qhash.h"
49#include "qstack.h"
50#include "qlayout.h"
51#include "qtextcodec.h"
52#include "qinputcontext.h"
53#include "qdesktopwidget.h"
54
55#include "qwsdisplay_qws.h"
56#include "private/qwsdisplay_qws_p.h"
57#include "qscreen_qws.h"
58#include "qwsmanager_qws.h"
59#include <private/qwsmanager_p.h>
60#include <private/qbackingstore_p.h>
61#include <private/qwindowsurface_qws_p.h>
62#include <private/qwslock_p.h>
63#include "qpaintengine.h"
64
65#include "qdebug.h"
66
67#include "qwidget_p.h"
68
69QT_BEGIN_NAMESPACE
70
71QT_USE_NAMESPACE
72
73extern int *qt_last_x;
74extern int *qt_last_y;
75extern WId qt_last_cursor;
76extern bool qws_overrideCursor;
77extern QWidget *qt_pressGrab;
78extern QWidget *qt_mouseGrb;
79
80static QWidget *keyboardGrb = 0;
81
82static int takeLocalId()
83{
84 static int n=-1000;
85 return --n;
86}
87
88class QWSServer;
89extern QWSServer *qwsServer;
90
91static inline bool isServerProcess()
92{
93 return (qwsServer != 0);
94}
95
96/*****************************************************************************
97 QWidget member functions
98 *****************************************************************************/
99
100void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool /*destroyOldWindow*/)
101{
102 Q_Q(QWidget);
103 Qt::WindowType type = q->windowType();
104
105 // Make sure the WindowTitleHint is on if any of the title bar hints are set
106 // Note: This might be moved to cross-platform QWidgetPrivate::adjustFlags()
107 if ( !(data.window_flags & Qt::CustomizeWindowHint) && (
108 (data.window_flags & Qt::WindowSystemMenuHint) ||
109 (data.window_flags & Qt::WindowContextHelpButtonHint) ||
110 (data.window_flags & Qt::WindowMinimizeButtonHint) ||
111 (data.window_flags & Qt::WindowMaximizeButtonHint) ||
112 (data.window_flags & Qt::WindowCloseButtonHint) ) ) {
113 data.window_flags |= Qt::WindowTitleHint;
114 }
115
116 // Decoration plugins on QWS don't support switching on the close button on its own
117 if (data.window_flags & Qt::WindowCloseButtonHint)
118 data.window_flags |= Qt::WindowSystemMenuHint;
119
120 Qt::WindowFlags flags = data.window_flags;
121
122 data.alloc_region_index = -1;
123
124 // we don't have a "Drawer" window type
125 if (type == Qt::Drawer) {
126 type = Qt::Widget;
127 flags &= ~Qt::WindowType_Mask;
128 }
129
130
131 bool topLevel = (flags & Qt::Window);
132 bool popup = (type == Qt::Popup);
133 bool dialog = (type == Qt::Dialog
134 || type == Qt::Sheet
135 || (flags & Qt::MSWindowsFixedSizeDialogHint));
136 bool desktop = (type == Qt::Desktop);
137 bool tool = (type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip);
138
139
140#ifndef QT_NO_WARNING_OUTPUT
141 static bool toolWarningShown = false;
142 if (!toolWarningShown && type == Qt::Tool && !(flags & Qt::FramelessWindowHint)) {
143 qWarning("Qt for Embedded Linux " QT_VERSION_STR " does not support tool windows with frames.\n"
144 "This behavior will change in a later release. To ensure compatibility with\n"
145 "future versions, use (Qt::Tool | Qt::FramelessWindowHint).");
146 toolWarningShown = true;
147 }
148#endif
149
150 WId id;
151 QWSDisplay* dpy = QWidget::qwsDisplay();
152
153 if (!window) // always initialize
154 initializeWindow = true;
155
156 // use the size of the primary screen to determine the default window size
157 QList<QScreen *> screens = qt_screen->subScreens();
158 if (screens.isEmpty())
159 screens.append(qt_screen);
160 int sw = screens[0]->width();
161 int sh = screens[0]->height();
162
163 if (desktop) { // desktop widget
164 dialog = popup = false; // force these flags off
165 data.crect.setRect(0, 0, sw, sh);
166 } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
167 int width = sw / 2;
168 int height = 4 * sh / 10;
169 if (extra) {
170 width = qMax(qMin(width, extra->maxw), extra->minw);
171 height = qMax(qMin(height, extra->maxh), extra->minh);
172 }
173 data.crect.setSize(QSize(width, height));
174 }
175
176 if (window) { // override the old window
177 id = window;
178 setWinId(window);
179 } else if (desktop) { // desktop widget
180 id = (WId)-2; // id = root window
181#if 0
182 QWidget *otherDesktop = q->find(id); // is there another desktop?
183 if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
184 otherDesktop->d_func()->setWinId(0); // remove id from widget mapper
185 setWinId(id); // make sure otherDesktop is
186 otherDesktop->d_func()->setWinId(id); // found first
187 } else
188#endif
189 {
190 setWinId(id);
191 }
192 } else {
193 id = topLevel ? dpy->takeId() : takeLocalId();
194 setWinId(id); // set widget id/handle + hd
195 }
196
197
198 bool hasFrame = true;
199 if (topLevel) {
200 if (desktop || popup || tool || q->testAttribute(Qt::WA_DontShowOnScreen))
201 hasFrame = false;
202 else
203 hasFrame = !(flags & Qt::FramelessWindowHint);
204 }
205 if (desktop) {
206 q->setAttribute(Qt::WA_WState_Visible);
207 } else if (topLevel) { // set X cursor
208 //QCursor *oc = QApplication::overrideCursor();
209 if (initializeWindow) {
210 //XXX XDefineCursor(dpy, winid, oc ? oc->handle() : cursor().handle());
211 }
212 QWidget::qwsDisplay()->nameRegion(q->internalWinId(), q->objectName(), q->windowTitle());
213 }
214
215 if (topLevel) {
216 createTLExtra();
217 QTLWExtra *topextra = extra->topextra;
218#ifndef QT_NO_QWS_MANAGER
219 if (hasFrame) {
220 // get size of wm decoration and make the old crect the new frect
221 QRect cr = data.crect;
222 QRegion r = QApplication::qwsDecoration().region(q, cr) | cr;
223 QRect br(r.boundingRect());
224 topextra->frameStrut.setCoords(cr.x() - br.x(),
225 cr.y() - br.y(),
226 br.right() - cr.right(),
227 br.bottom() - cr.bottom());
228 if (!q->testAttribute(Qt::WA_Moved) || topextra->posFromMove)
229 data.crect.translate(topextra->frameStrut.left(), topextra->frameStrut.top());
230 if (!topData()->qwsManager) {
231 topData()->qwsManager = new QWSManager(q);
232 if((q->data->window_state & ~Qt::WindowActive) == Qt::WindowMaximized)
233 topData()->qwsManager->maximize();
234 }
235
236 } else if (topData()->qwsManager) {
237 delete topData()->qwsManager;
238 topData()->qwsManager = 0;
239 data.crect.translate(-topextra->frameStrut.left(), -topextra->frameStrut.top());
240 topextra->frameStrut.setCoords(0, 0, 0, 0);
241 }
242#endif
243 if (!topextra->caption.isEmpty())
244 setWindowTitle_helper(topextra->caption);
245
246 //XXX If we are session managed, inform the window manager about it
247 } else {
248 if (extra && extra->topextra) { // already allocated due to reparent?
249 extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
250 }
251 //updateRequestedRegion(mapToGlobal(QPoint(0,0)));
252 }
253}
254
255
256void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
257{
258 Q_D(QWidget);
259
260 if (!isWindow() && parentWidget())
261 parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
262
263 d->deactivateWidgetCleanup();
264 if (testAttribute(Qt::WA_WState_Created)) {
265 setAttribute(Qt::WA_WState_Created, false);
266 QObjectList childObjects = children();
267 for (int i = 0; i < childObjects.size(); ++i) {
268 QObject *obj = childObjects.at(i);
269 if (obj->isWidgetType())
270 static_cast<QWidget*>(obj)->destroy(destroySubWindows,
271 destroySubWindows);
272 }
273 releaseMouse();
274 if (qt_pressGrab == this)
275 qt_pressGrab = 0;
276
277 if (keyboardGrb == this)
278 releaseKeyboard();
279 if (testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal
280 QApplicationPrivate::leaveModal(this);
281 else if ((windowType() == Qt::Popup))
282 qApp->d_func()->closePopup(this);
283#ifndef QT_NO_IM
284 if (d->ic) {
285 delete d->ic;
286 d->ic =0;
287 } else {
288 // release previous focus information participating with
289 // preedit preservation of qic -- while we still have a winId
290 QInputContext *qic = QApplicationPrivate::inputContext;
291 if (qic)
292 qic->widgetDestroyed(this);
293 }
294#endif //QT_NO_IM
295
296 if ((windowType() == Qt::Desktop)) {
297 } else {
298 if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
299 d->hide_sys();
300 }
301 if (destroyWindow && isWindow()) {
302 if (d->extra && d->extra->topextra && d->extra->topextra->backingStore)
303 d->extra->topextra->backingStore->windowSurface->setGeometry(QRect());
304 qwsDisplay()->destroyRegion(internalWinId());
305 }
306 }
307 QT_TRY {
308 d->setWinId(0);
309 } QT_CATCH (const std::bad_alloc &) {
310 // swallow - destructors must not throw
311 }
312 }
313}
314
315
316void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
317{
318 Q_Q(QWidget);
319 bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
320 if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
321 q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
322#ifndef QT_NO_CURSOR
323 QCursor oldcurs;
324 bool setcurs=q->testAttribute(Qt::WA_SetCursor);
325 if (setcurs) {
326 oldcurs = q->cursor();
327 q->unsetCursor();
328 }
329#endif
330
331 WId old_winid = data.winid;
332 if ((q->windowType() == Qt::Desktop))
333 old_winid = 0;
334
335 if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_WState_Created))
336 hide_sys();
337
338 setWinId(0);
339
340 if (parent != newparent) {
341 QWidget *oldparent = q->parentWidget();
342 QObjectPrivate::setParent_helper(newparent);
343 if (oldparent) {
344// oldparent->d_func()->setChildrenAllocatedDirty();
345// oldparent->data->paintable_region_dirty = true;
346 }
347 if (newparent) {
348// newparent->d_func()->setChildrenAllocatedDirty();
349// newparent->data->paintable_region_dirty = true;
350 //@@@@@@@
351 }
352 }
353 Qt::FocusPolicy fp = q->focusPolicy();
354 QSize s = q->size();
355 //QBrush bgc = background(); // save colors
356 bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
357
358 data.window_flags = f;
359 q->setAttribute(Qt::WA_WState_Created, false);
360 q->setAttribute(Qt::WA_WState_Visible, false);
361 q->setAttribute(Qt::WA_WState_Hidden, false);
362 adjustFlags(data.window_flags, q);
363 // keep compatibility with previous versions, we need to preserve the created state
364 // (but we recreate the winId for the widget being reparented, again for compatibility)
365 if (wasCreated || (!q->isWindow() && newparent->testAttribute(Qt::WA_WState_Created)))
366 createWinId();
367 if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
368 q->setAttribute(Qt::WA_WState_Hidden);
369 q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
370
371 if (q->isWindow()) {
372 QRect fs = frameStrut();
373 data.crect = QRect(fs.left(), fs.top(), s.width(), s.height());
374 if ((data.window_flags & Qt::FramelessWindowHint) && extra && extra->topextra)
375 extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
376 } else {
377 data.crect = QRect(0, 0, s.width(), s.height());
378 }
379
380 q->setFocusPolicy(fp);
381 if (extra && !extra->mask.isEmpty()) {
382 QRegion r = extra->mask;
383 extra->mask = QRegion();
384 q->setMask(r);
385 }
386 if ((int)old_winid > 0) {
387 QWidget::qwsDisplay()->destroyRegion(old_winid);
388 extra->topextra->backingStore->windowSurface->setGeometry(QRect());
389 }
390#ifndef QT_NO_CURSOR
391 if (setcurs) {
392 q->setCursor(oldcurs);
393 }
394#endif
395}
396
397
398QPoint QWidget::mapToGlobal(const QPoint &pos) const
399{
400 int x=pos.x(), y=pos.y();
401 const QWidget* w = this;
402 while (w) {
403 x += w->data->crect.x();
404 y += w->data->crect.y();
405 w = w->isWindow() ? 0 : w->parentWidget();
406 }
407 return QPoint(x, y);
408}
409
410QPoint QWidget::mapFromGlobal(const QPoint &pos) const
411{
412 int x=pos.x(), y=pos.y();
413 const QWidget* w = this;
414 while (w) {
415 x -= w->data->crect.x();
416 y -= w->data->crect.y();
417 w = w->isWindow() ? 0 : w->parentWidget();
418 }
419 return QPoint(x, y);
420}
421
422#if 0 // #####
423void QWidget::setMicroFocusHint(int x, int y, int width, int height,
424 bool text, QFont *)
425{
426 if (QRect(x, y, width, height) != microFocusHint()) {
427 d->createExtra();
428 d->extra->micro_focus_hint.setRect(x, y, width, height);
429 }
430#ifndef QT_NO_QWS_INPUTMETHODS
431 if (text) {
432 QWidget *tlw = window();
433 int winid = tlw->internalWinId();
434 QPoint p(x, y + height);
435 QPoint gp = mapToGlobal(p);
436
437 QRect r = QRect(mapToGlobal(QPoint(0,0)),
438 size());
439
440 r.setBottom(tlw->geometry().bottom());
441
442 //qDebug("QWidget::setMicroFocusHint %d %d %d %d", r.x(),
443 // r.y(), r.width(), r.height());
444 QInputContext::setMicroFocusWidget(this);
445
446 qwsDisplay()->setIMInfo(winid, gp.x(), gp.y(), r);
447
448 //send font info, ###if necessary
449 qwsDisplay()->setInputFont(winid, font());
450 }
451#endif
452}
453#endif
454
455void QWidgetPrivate::updateSystemBackground() {}
456
457#ifndef QT_NO_CURSOR
458void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
459{
460 Q_UNUSED(cursor);
461 Q_Q(QWidget);
462 if (q->isVisible())
463 updateCursor();
464}
465
466void QWidgetPrivate::unsetCursor_sys()
467{
468 Q_Q(QWidget);
469 if (q->isVisible())
470 updateCursor();
471}
472#endif //QT_NO_CURSOR
473
474void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
475{
476 Q_Q(QWidget);
477 QWidget::qwsDisplay()->setWindowCaption(q, caption);
478}
479
480void QWidgetPrivate::setWindowIcon_sys(bool /*forceReset*/)
481{
482#if 0
483 QTLWExtra* x = d->topData();
484 delete x->icon;
485 x->icon = 0;
486 QBitmap mask;
487 if (unscaledPixmap.isNull()) {
488 } else {
489 QImage unscaledIcon = unscaledPixmap.toImage();
490 QPixmap pixmap =
491 QPixmap::fromImage(unscaledIcon.scale(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
492 x->icon = new QPixmap(pixmap);
493 mask = pixmap.mask() ? *pixmap.mask() : pixmap.createHeuristicMask();
494 }
495#endif
496}
497
498void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
499{
500 Q_UNUSED(iconText);
501}
502
503void QWidget::grabMouse()
504{
505 if (qt_mouseGrb)
506 qt_mouseGrb->releaseMouse();
507
508 qwsDisplay()->grabMouse(this,true);
509
510 qt_mouseGrb = this;
511 qt_pressGrab = 0;
512}
513
514#ifndef QT_NO_CURSOR
515void QWidget::grabMouse(const QCursor &cursor)
516{
517 if (qt_mouseGrb)
518 qt_mouseGrb->releaseMouse();
519
520 qwsDisplay()->grabMouse(this,true);
521 qwsDisplay()->selectCursor(this, cursor.handle());
522 qt_mouseGrb = this;
523 qt_pressGrab = 0;
524}
525#endif
526
527void QWidget::releaseMouse()
528{
529 if (qt_mouseGrb == this) {
530 qwsDisplay()->grabMouse(this,false);
531 qt_mouseGrb = 0;
532 }
533}
534
535void QWidget::grabKeyboard()
536{
537 if (keyboardGrb)
538 keyboardGrb->releaseKeyboard();
539 qwsDisplay()->grabKeyboard(this, true);
540 keyboardGrb = this;
541}
542
543void QWidget::releaseKeyboard()
544{
545 if (keyboardGrb == this) {
546 qwsDisplay()->grabKeyboard(this, false);
547 keyboardGrb = 0;
548 }
549}
550
551
552QWidget *QWidget::mouseGrabber()
553{
554 if (qt_mouseGrb)
555 return qt_mouseGrb;
556 return qt_pressGrab;
557}
558
559
560QWidget *QWidget::keyboardGrabber()
561{
562 return keyboardGrb;
563}
564
565void QWidget::activateWindow()
566{
567 QWidget *tlw = window();
568 if (tlw->isVisible()) {
569 Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
570 qwsDisplay()->requestFocus(tlw->internalWinId(), true);
571 }
572}
573
574void QWidgetPrivate::show_sys()
575{
576 Q_Q(QWidget);
577 q->setAttribute(Qt::WA_Mapped);
578 if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
579 invalidateBuffer(q->rect());
580 return;
581 }
582
583 if (q->isWindow()) {
584
585
586 if (!q->testAttribute(Qt::WA_ShowWithoutActivating)
587 && q->windowType() != Qt::Popup
588 && q->windowType() != Qt::Tool
589 && q->windowType() != Qt::ToolTip) {
590 QWidget::qwsDisplay()->requestFocus(data.winid,true);
591 }
592
593
594 if (QWindowSurface *surface = q->windowSurface()) {
595 const QRect frameRect = q->frameGeometry();
596 if (surface->geometry() != frameRect)
597 surface->setGeometry(frameRect);
598 }
599
600 QRegion r = localRequestedRegion();
601#ifndef QT_NO_QWS_MANAGER
602 if (extra && extra->topextra && extra->topextra->qwsManager) {
603 r.translate(data.crect.topLeft());
604 r += extra->topextra->qwsManager->region();
605 r.translate(-data.crect.topLeft());
606 }
607#endif
608 data.fstrut_dirty = true;
609 invalidateBuffer(r);
610 bool staysontop =
611 (q->windowFlags() & Qt::WindowStaysOnTopHint)
612 || q->windowType() == Qt::Popup;
613 if (!staysontop && q->parentWidget()) { // if our parent stays on top, so must we
614 QWidget *ptl = q->parentWidget()->window();
615 if (ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
616 staysontop = true;
617 }
618
619 QWSChangeAltitudeCommand::Altitude altitude;
620 altitude = staysontop ? QWSChangeAltitudeCommand::StaysOnTop : QWSChangeAltitudeCommand::Raise;
621 QWidget::qwsDisplay()->setAltitude(data.winid, altitude, true);
622 if (!q->objectName().isEmpty()) {
623 QWidget::qwsDisplay()->setWindowCaption(q, q->windowTitle());
624 }
625 }
626#ifdef Q_BACKINGSTORE_SUBSURFACES
627 else if ( extra && extra->topextra && extra->topextra->windowSurface) {
628 QWSWindowSurface *surface;
629 surface = static_cast<QWSWindowSurface*>(q->windowSurface());
630 const QPoint p = q->mapToGlobal(QPoint());
631 surface->setGeometry(QRect(p, q->size()));
632 }
633#endif
634
635 if (!q->window()->data->in_show) {
636 invalidateBuffer(q->rect());
637 }
638}
639
640
641void QWidgetPrivate::hide_sys()
642{
643 Q_Q(QWidget);
644 deactivateWidgetCleanup();
645
646 if (q->isWindow()) {
647 q->releaseMouse();
648// requestWindowRegion(QRegion());
649
650 if (extra->topextra->backingStore)
651 extra->topextra->backingStore->releaseBuffer();
652
653
654 QWidget::qwsDisplay()->requestFocus(data.winid,false);
655 } else {
656 QWidget *p = q->parentWidget();
657 if (p &&p->isVisible()) {
658 invalidateBuffer(q->rect());
659 }
660 }
661}
662
663
664
665static Qt::WindowStates effectiveState(Qt::WindowStates state)
666 {
667 if (state & Qt::WindowMinimized)
668 return Qt::WindowMinimized;
669 else if (state & Qt::WindowFullScreen)
670 return Qt::WindowFullScreen;
671 else if (state & Qt::WindowMaximized)
672 return Qt::WindowMaximized;
673 return Qt::WindowNoState;
674 }
675
676void QWidgetPrivate::setMaxWindowState_helper()
677{
678 // in_set_window_state is usually set in setWindowState(), but this
679 // function is used in other functions as well
680 // (e.g QApplicationPrivate::setMaxWindowRect())
681 const uint old_state = data.in_set_window_state;
682 data.in_set_window_state = 1;
683
684#ifndef QT_NO_QWS_MANAGER
685 if (extra && extra->topextra && extra->topextra->qwsManager)
686 extra->topextra->qwsManager->maximize();
687 else
688#endif
689 {
690 Q_Q(QWidget);
691 const QDesktopWidget *desktop = QApplication::desktop();
692 const int screen = desktop->screenNumber(q);
693 const QRect maxWindowRect = desktop->availableGeometry(screen);
694 q->setGeometry(maxWindowRect);
695 }
696 data.in_set_window_state = old_state;
697}
698
699void QWidgetPrivate::setFullScreenSize_helper()
700{
701 Q_Q(QWidget);
702
703 const uint old_state = data.in_set_window_state;
704 data.in_set_window_state = 1;
705
706 const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
707 q->move(screen.topLeft());
708 q->resize(screen.size());
709
710 data.in_set_window_state = old_state;
711}
712
713void QWidget::setWindowState(Qt::WindowStates newstate)
714{
715 Q_D(QWidget);
716 Qt::WindowStates oldstate = windowState();
717 if (oldstate == newstate)
718 return;
719 if (isWindow() && !testAttribute(Qt::WA_WState_Created))
720 create();
721
722 data->window_state = newstate;
723 data->in_set_window_state = 1;
724 bool needShow = false;
725 Qt::WindowStates newEffectiveState = effectiveState(newstate);
726 Qt::WindowStates oldEffectiveState = effectiveState(oldstate);
727 if (isWindow() && newEffectiveState != oldEffectiveState) {
728 d->createTLExtra();
729 if (oldEffectiveState == Qt::WindowNoState) { //normal
730 d->topData()->normalGeometry = geometry();
731 } else if (oldEffectiveState == Qt::WindowFullScreen) {
732 setParent(0, d->topData()->savedFlags);
733 needShow = true;
734 } else if (oldEffectiveState == Qt::WindowMinimized) {
735 needShow = true;
736 }
737
738 if (newEffectiveState == Qt::WindowMinimized) {
739 //### not ideal...
740 hide();
741 needShow = false;
742 } else if (newEffectiveState == Qt::WindowFullScreen) {
743 d->topData()->savedFlags = windowFlags();
744 setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
745 d->setFullScreenSize_helper();
746 raise();
747 needShow = true;
748 } else if (newEffectiveState == Qt::WindowMaximized) {
749 createWinId();
750 d->setMaxWindowState_helper();
751 } else { //normal
752 QRect r = d->topData()->normalGeometry;
753 if (r.width() >= 0) {
754 d->topData()->normalGeometry = QRect(0,0,-1,-1);
755 setGeometry(r);
756 }
757 }
758 }
759 data->in_set_window_state = 0;
760
761 if (needShow)
762 show();
763
764 if (newstate & Qt::WindowActive)
765 activateWindow();
766
767 QWindowStateChangeEvent e(oldstate);
768 QApplication::sendEvent(this, &e);
769}
770
771void QWidgetPrivate::setFocus_sys()
772{
773
774}
775
776void QWidgetPrivate::raise_sys()
777{
778 Q_Q(QWidget);
779 //@@@ transaction
780 if (q->isWindow()) {
781 Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
782 QWidget::qwsDisplay()->setAltitude(q->internalWinId(),
783 QWSChangeAltitudeCommand::Raise);
784 // XXX: subsurfaces?
785#ifdef QT_NO_WINDOWGROUPHINT
786#else
787 QObjectList childObjects = q->children();
788 if (!childObjects.isEmpty()) {
789 QWidgetList toraise;
790 for (int i = 0; i < childObjects.size(); ++i) {
791 QObject *obj = childObjects.at(i);
792 if (obj->isWidgetType()) {
793 QWidget* w = static_cast<QWidget*>(obj);
794 if (w->isWindow())
795 toraise.append(w);
796 }
797 }
798
799 for (int i = 0; i < toraise.size(); ++i) {
800 QWidget *w = toraise.at(i);
801 if (w->isVisible())
802 w->raise();
803 }
804 }
805#endif // QT_NO_WINDOWGROUPHINT
806 }
807}
808
809void QWidgetPrivate::lower_sys()
810{
811 Q_Q(QWidget);
812 if (q->isWindow()) {
813 Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
814 QWidget::qwsDisplay()->setAltitude(data.winid,
815 QWSChangeAltitudeCommand::Lower);
816 } else if (QWidget *p = q->parentWidget()) {
817 setDirtyOpaqueRegion();
818 p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
819 }
820}
821
822void QWidgetPrivate::stackUnder_sys(QWidget*)
823{
824 Q_Q(QWidget);
825 if (QWidget *p = q->parentWidget()) {
826 setDirtyOpaqueRegion();
827 p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
828 }
829}
830
831void QWidgetPrivate::moveSurface(QWindowSurface *surface, const QPoint &offset)
832{
833 QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surface);
834 if (!s->move(offset))
835 s->invalidateBuffer();
836
837 QWSDisplay::instance()->moveRegion(s->winId(), offset.x(), offset.y());
838}
839
840void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
841{
842 Q_Q(QWidget);
843 if (extra) { // any size restrictions?
844 w = qMin(w,extra->maxw);
845 h = qMin(h,extra->maxh);
846 w = qMax(w,extra->minw);
847 h = qMax(h,extra->minh);
848 }
849
850 QPoint oldp = q->geometry().topLeft();
851 QSize olds = q->size();
852 QRect r(x, y, w, h);
853
854 bool isResize = olds != r.size();
855 isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
856
857 // We only care about stuff that changes the geometry, or may
858 // cause the window manager to change its state
859 if (r.size() == olds && oldp == r.topLeft())
860 return;
861
862 if (!data.in_set_window_state) {
863 q->data->window_state &= ~Qt::WindowMaximized;
864 q->data->window_state &= ~Qt::WindowFullScreen;
865 if (q->isWindow())
866 topData()->normalGeometry = QRect(0, 0, -1, -1);
867 }
868 QPoint oldPos = q->pos();
869 data.crect = r;
870
871 if ((q->windowType() == Qt::Desktop))
872 return;
873
874 if (q->isVisible()) {
875
876 bool toplevelMove = false;
877 QWSWindowSurface *surface = 0;
878
879 if (q->isWindow()) {
880 //### ConfigPending not implemented, do we need it?
881 //setAttribute(Qt::WA_WState_ConfigPending);
882 const QWidgetBackingStore *bs = maybeBackingStore();
883 if (bs)
884 surface = static_cast<QWSWindowSurface*>(bs->windowSurface);
885 if (isMove && !isResize && surface) {
886 const QPoint offset(x - oldp.x(), y - oldp.y());
887 moveSurface(surface, offset);
888 toplevelMove = true; //server moves window, but we must send moveEvent, which might trigger painting
889
890#ifdef Q_BACKINGSTORE_SUBSURFACES
891 QList<QWindowSurface*> surfaces = bs->subSurfaces;
892 for (int i = 0; i < surfaces.size(); ++i)
893 moveSurface(surfaces.at(i), offset);
894#endif
895 } else {
896 updateFrameStrut();
897 }
898 }
899
900 if (!toplevelMove) {
901 if (q->isWindow()) {
902 if (surface)
903 surface->setGeometry(q->frameGeometry());
904 else
905 invalidateBuffer(q->rect()); //###
906
907#ifdef Q_BACKINGSTORE_SUBSURFACES
908 // XXX: should not resize subsurfaces. Children within a layout
909 // will be resized automatically while children with a static
910 // geometry should get a new clip region instead.
911 const QRect clipRect = q->geometry();
912 QWidgetBackingStore *bs = maybeBackingStore();
913 QList<QWindowSurface*> surfaces = bs->subSurfaces;
914 for (int i = 0; i < surfaces.size(); ++i) {
915 QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surfaces.at(i));
916 QRect srect = s->geometry();
917 s->setGeometry(clipRect & srect);
918 }
919#endif
920 }
921#ifdef Q_BACKINGSTORE_SUBSURFACES
922 // XXX: merge this case with the isWindow() case
923 else if (maybeTopData() && maybeTopData()->windowSurface) {
924 QWSWindowSurface *surface;
925 surface = static_cast<QWSWindowSurface*>(q->windowSurface());
926 if (isMove && !isResize) {
927 moveSurface(surface, QPoint(x - oldp.x(), y - oldp.y()));
928 } else {
929 const QPoint p = q->mapToGlobal(QPoint());
930 surface->setGeometry(QRect(p, QSize(w, h)));
931 }
932 }
933#endif
934 else {
935 if (isMove && !isResize)
936 moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
937 else
938 invalidateBuffer_resizeHelper(oldPos, olds);
939 }
940 }
941
942 //### must have frame geometry correct before sending move/resize events
943 if (isMove) {
944 QMoveEvent e(q->pos(), oldPos);
945 QApplication::sendEvent(q, &e);
946 }
947 if (isResize) {
948 QResizeEvent e(r.size(), olds);
949 QApplication::sendEvent(q, &e);
950 }
951
952 } else { // not visible
953 if (isMove && q->pos() != oldPos)
954 q->setAttribute(Qt::WA_PendingMoveEvent, true);
955 if (isResize)
956 q->setAttribute(Qt::WA_PendingResizeEvent, true);
957 }
958}
959
960void QWidgetPrivate::setConstraints_sys()
961{
962}
963
964QScreen* QWidgetPrivate::getScreen() const
965{
966 Q_Q(const QWidget);
967
968 const QList<QScreen*> subScreens = qt_screen->subScreens();
969 if (subScreens.isEmpty() || q->windowType() == Qt::Desktop)
970 return qt_screen;
971
972 const int screen = QApplication::desktop()->screenNumber(q);
973
974 return qt_screen->subScreens().at(screen < 0 ? 0 : screen);
975}
976
977void QWidgetPrivate::scroll_sys(int dx, int dy)
978{
979 Q_Q(QWidget);
980 scrollChildren(dx, dy);
981 scrollRect(q->rect(), dx, dy);
982}
983
984void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
985{
986 scrollRect(r, dx, dy);
987}
988
989int QWidget::metric(PaintDeviceMetric m) const
990{
991 Q_D(const QWidget);
992
993 int val;
994 if (m == PdmWidth) {
995 val = data->crect.width();
996 } else if (m == PdmWidthMM) {
997 const QScreen *screen = d->getScreen();
998 val = data->crect.width() * screen->physicalWidth() / screen->width();
999 } else if (m == PdmHeight) {
1000 val = data->crect.height();
1001 } else if (m == PdmHeightMM) {
1002 const QScreen *screen = d->getScreen();
1003 val = data->crect.height() * screen->physicalHeight() / screen->height();
1004 } else if (m == PdmDepth) {
1005 return qwsDisplay()->depth();
1006 } else if (m == PdmDpiX || m == PdmPhysicalDpiX) {
1007 if (d->extra && d->extra->customDpiX)
1008 return d->extra->customDpiX;
1009 else if (d->parent)
1010 return static_cast<QWidget *>(d->parent)->metric(m);
1011 const QScreen *screen = d->getScreen();
1012 return qRound(screen->width() / double(screen->physicalWidth() / 25.4));
1013 } else if (m == PdmDpiY || m == PdmPhysicalDpiY) {
1014 if (d->extra && d->extra->customDpiY)
1015 return d->extra->customDpiY;
1016 else if (d->parent)
1017 return static_cast<QWidget *>(d->parent)->metric(m);
1018 const QScreen *screen = d->getScreen();
1019 return qRound(screen->height() / double(screen->physicalHeight() / 25.4));
1020 } else {
1021 val = QPaintDevice::metric(m);// XXX
1022 }
1023 return val;
1024}
1025
1026void QWidgetPrivate::createSysExtra()
1027{
1028}
1029
1030void QWidgetPrivate::deleteSysExtra()
1031{
1032}
1033
1034void QWidgetPrivate::createTLSysExtra()
1035{
1036#ifndef QT_NO_QWS_MANAGER
1037 extra->topextra->qwsManager = 0;
1038#endif
1039}
1040
1041void QWidgetPrivate::deleteTLSysExtra()
1042{
1043}
1044
1045void QWidgetPrivate::registerDropSite(bool on)
1046{
1047 Q_UNUSED(on);
1048}
1049
1050QRegion QWidgetPrivate::localRequestedRegion() const
1051{
1052 Q_Q(const QWidget);
1053 QRegion r(q->rect());
1054 if (extra && !extra->mask.isEmpty())
1055 r &= extra->mask;
1056
1057 return r;
1058}
1059
1060QRegion QWidgetPrivate::localAllocatedRegion() const
1061{
1062 Q_Q(const QWidget);
1063
1064 QWidgetBackingStore *wbs = q->window()->d_func()->maybeBackingStore();
1065
1066 QWindowSurface *ws = wbs ? wbs->windowSurface : 0;
1067 if (!ws)
1068 return QRegion();
1069 QRegion r = static_cast<QWSWindowSurface*>(ws)->clipRegion();
1070 if (!q->isWindow()) {
1071 QPoint off = q->mapTo(q->window(), QPoint());
1072 r &= localRequestedRegion().translated(off);
1073 r.translate(-off);
1074 }
1075 return r;
1076}
1077
1078inline bool QRect::intersects(const QRect &r) const
1079{
1080 return (qMax(x1, r.x1) <= qMin(x2, r.x2) &&
1081 qMax(y1, r.y1) <= qMin(y2, r.y2));
1082}
1083
1084void QWidgetPrivate::setMask_sys(const QRegion &region)
1085{
1086 Q_UNUSED(region);
1087 Q_Q(QWidget);
1088
1089 if (!q->isVisible() || !q->isWindow())
1090 return;
1091
1092 data.fstrut_dirty = true;
1093 invalidateBuffer(q->rect());
1094 QWindowSurface *surface = extra->topextra->backingStore->windowSurface;
1095 if (surface) {
1096 // QWSWindowSurface::setGeometry() returns without doing anything
1097 // if old geom == new geom. Therefore, we need to reset the old value.
1098 surface->QWindowSurface::setGeometry(QRect());
1099 surface->setGeometry(q->frameGeometry());
1100 }
1101}
1102
1103void QWidgetPrivate::updateFrameStrut()
1104{
1105 Q_Q(QWidget);
1106
1107 if(!q->isVisible() || (q->windowType() == Qt::Desktop)) {
1108 data.fstrut_dirty = q->isVisible();
1109 return;
1110 }
1111
1112#ifndef QT_NO_QWS_MANAGER
1113 if (extra && extra->topextra && extra->topextra->qwsManager) {
1114 QTLWExtra *topextra = extra->topextra;
1115 const QRect oldFrameStrut = topextra->frameStrut;
1116 const QRect contents = data.crect;
1117 QRegion r = localRequestedRegion().translated(contents.topLeft());
1118 r += extra->topextra->qwsManager->region();
1119 const QRect frame = r.boundingRect();
1120
1121 topextra->frameStrut.setCoords(contents.left() - frame.left(),
1122 contents.top() - frame.top(),
1123 frame.right() - contents.right(),
1124 frame.bottom() - contents.bottom());
1125 topextra->qwsManager->repaintRegion(QDecoration::All, QDecoration::Normal);
1126 }
1127#endif
1128 data.fstrut_dirty = false;
1129}
1130
1131#ifndef QT_NO_CURSOR
1132void QWidgetPrivate::updateCursor() const
1133{
1134 Q_Q(const QWidget);
1135
1136 if (QApplication::overrideCursor())
1137 return;
1138
1139 if (qt_last_x
1140 && (!QWidget::mouseGrabber() || QWidget::mouseGrabber() == q)
1141 && qt_last_cursor != (WId)q->cursor().handle())
1142 {
1143 const QPoint pos(*qt_last_x, *qt_last_y);
1144 const QPoint offset = q->mapToGlobal(QPoint());
1145 if (!localAllocatedRegion().contains(pos - offset))
1146 return;
1147
1148 const QWidget *w = q->childAt(q->mapFromGlobal(pos));
1149 if (!w || w->cursor().handle() == q->cursor().handle())
1150 QWidget::qwsDisplay()->selectCursor(const_cast<QWidget*>(q),
1151 q->cursor().handle());
1152 }
1153}
1154#endif
1155
1156void QWidgetPrivate::setWindowOpacity_sys(qreal level)
1157{
1158 Q_Q(QWidget);
1159 Q_UNUSED(level);
1160 createWinId();
1161 QWidget::qwsDisplay()->setOpacity(q->data->winid, topData()->opacity);
1162}
1163
1164//static QSingleCleanupHandler<QWSPaintEngine> qt_paintengine_cleanup_handler;
1165//static QWSPaintEngine *qt_widget_paintengine = 0;
1166QPaintEngine *QWidget::paintEngine() const
1167{
1168 qWarning("QWidget::paintEngine: Should no longer be called");
1169 return 0; //##### @@@
1170// if (!qt_widget_paintengine) {
1171// qt_widget_paintengine = new QRasterPaintEngine();
1172// qt_paintengine_cleanup_handler.set(&qt_widget_paintengine);
1173// }
1174// if (qt_widget_paintengine->isActive()) {
1175// if (d->extraPaintEngine)
1176// return d->extraPaintEngine;
1177// const_cast<QWidget *>(this)->d_func()->extraPaintEngine = new QRasterPaintEngine();
1178// return d->extraPaintEngine;
1179// }
1180// return qt_widget_paintengine;
1181}
1182
1183QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
1184{
1185 Q_Q(QWidget);
1186 if (q->windowType() == Qt::Desktop)
1187 return 0;
1188 q->ensurePolished();
1189 return qt_screen->createSurface(q);
1190}
1191
1192void QWidgetPrivate::setModal_sys()
1193{
1194}
1195
1196
1197QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.