Qt 4.8
qwidget_mac.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 /****************************************************************************
43 **
44 ** Copyright (c) 2007-2008, Apple, Inc.
45 **
46 ** All rights reserved.
47 **
48 ** Redistribution and use in source and binary forms, with or without
49 ** modification, are permitted provided that the following conditions are met:
50 **
51 ** * Redistributions of source code must retain the above copyright notice,
52 ** this list of conditions and the following disclaimer.
53 **
54 ** * Redistributions in binary form must reproduce the above copyright notice,
55 ** this list of conditions and the following disclaimer in the documentation
56 ** and/or other materials provided with the distribution.
57 **
58 ** * Neither the name of Apple, Inc. nor the names of its contributors
59 ** may be used to endorse or promote products derived from this software
60 ** without specific prior written permission.
61 **
62 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
63 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
64 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
65 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
66 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
67 ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
68 ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
69 ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
70 ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
71 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 **
74 ****************************************************************************/
75 
76 #include <private/qt_mac_p.h>
77 #include <private/qeventdispatcher_mac_p.h>
78 
79 #include "qapplication.h"
80 #include "qapplication_p.h"
81 #include "qbitmap.h"
82 #include "qcursor.h"
83 #include "qdesktopwidget.h"
84 #include "qevent.h"
85 #include "qfileinfo.h"
86 #include "qimage.h"
87 #include "qlayout.h"
88 #include "qmenubar.h"
89 #include <private/qbackingstore_p.h>
90 #include <private/qwindowsurface_mac_p.h>
91 #include <private/qpaintengine_mac_p.h>
92 #include "qpainter.h"
93 #include "qstyle.h"
94 #include "qtimer.h"
95 #include "qfocusframe.h"
96 #include "qdebug.h"
97 #include <private/qmainwindowlayout_p.h>
98 
99 #include <private/qabstractscrollarea_p.h>
100 #include <qabstractscrollarea.h>
101 #include <ApplicationServices/ApplicationServices.h>
102 #include <limits.h>
103 #include <private/qt_cocoa_helpers_mac_p.h>
104 #include <private/qcocoaview_mac_p.h>
105 #include <private/qcocoawindow_mac_p.h>
106 #include <private/qcocoawindowdelegate_mac_p.h>
107 #include <private/qcocoapanel_mac_p.h>
108 
109 #include "qwidget_p.h"
110 #include "qevent_p.h"
111 #include "qdnd_p.h"
112 #include <QtGui/qgraphicsproxywidget.h>
113 #include "qmainwindow.h"
114 
116 
117 // qmainwindow.cpp
119 
120 #define XCOORD_MAX 16383
121 #define WRECT_MAX 8191
122 
123 #ifndef QT_MAC_USE_COCOA
124 
125 extern "C" {
127  OptionBits) __attribute__ ((weak));
128 }
129 #define kHIViewScrollRectAdjustInvalid 1
130 #define kHIViewScrollRectDontInvalidateRevealedArea 2
131 #endif
132 
133 
134 /*****************************************************************************
135  QWidget debug facilities
136  *****************************************************************************/
137 //#define DEBUG_WINDOW_RGNS
138 //#define DEBUG_WINDOW_CREATE
139 //#define DEBUG_WINDOW_STATE
140 //#define DEBUG_WIDGET_PAINT
141 
142 /*****************************************************************************
143  QWidget globals
144  *****************************************************************************/
145 #ifndef QT_MAC_USE_COCOA
147 Q_GLOBAL_STATIC(WindowGroupHash, qt_mac_window_groups)
149 enum {
150  kWidgetPropertyQWidget = 'QWId' //QWidget *
151 };
152 #endif
153 
154 static bool qt_mac_raise_process = true;
158 
159 #ifndef QT_MAC_USE_COCOA
160 #ifdef QT_NAMESPACE
161 
162 // produce the string "com.trolltech.qt-namespace.widget", where "namespace" is the contents of QT_NAMESPACE.
163 #define SS(x) #x
164 #define S0(x) SS(x)
165 #define S "com.trolltech.qt-" S0(QT_NAMESPACE) ".widget"
166 
167 static CFStringRef kObjectQWidget = CFSTR(S);
168 
169 #undef SS
170 #undef S0
171 #undef S
172 
173 #else
174 static CFStringRef kObjectQWidget = CFSTR("com.trolltech.qt.widget");
175 #endif // QT_NAMESPACE
176 #endif // QT_MAC_USE_COCOA
177 
178 /*****************************************************************************
179  Externals
180  *****************************************************************************/
181 extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
182 extern QWidget *qt_mac_modal_blocked(QWidget *); //qapplication_mac.mm
183 extern void qt_event_request_activate(QWidget *); //qapplication_mac.mm
184 extern bool qt_event_remove_activate(); //qapplication_mac.mm
185 extern void qt_mac_event_release(QWidget *w); //qapplication_mac.mm
186 extern void qt_event_request_showsheet(QWidget *); //qapplication_mac.mm
187 extern void qt_event_request_window_change(QWidget *); //qapplication_mac.mm
188 extern QPointer<QWidget> qt_last_mouse_receiver; //qapplication_mac.mm
189 extern QPointer<QWidget> qt_last_native_mouse_receiver; //qt_cocoa_helpers_mac.mm
190 extern IconRef qt_mac_create_iconref(const QPixmap &); //qpixmap_mac.cpp
191 extern void qt_mac_set_cursor(const QCursor *, const QPoint &); //qcursor_mac.mm
192 extern void qt_mac_update_cursor(); //qcursor_mac.mm
193 extern bool qt_nograb();
194 extern CGImageRef qt_mac_create_cgimage(const QPixmap &, bool); //qpixmap_mac.cpp
195 extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
196 extern QRegion qt_mac_convert_mac_region(RgnHandle rgn); //qregion_mac.cpp
197 extern void qt_mac_setMouseGrabCursor(bool set, QCursor *cursor = 0); // qcursor_mac.mm
198 extern QPointer<QWidget> topLevelAt_cache; // qapplication_mac.mm
199 /*****************************************************************************
200  QWidget utility functions
201  *****************************************************************************/
204 {
205  int w = 0, h = 0;
206  CGDisplayCount cg_count;
207  CGGetActiveDisplayList(0, 0, &cg_count);
208  QVector<CGDirectDisplayID> displays(cg_count);
209  CGGetActiveDisplayList(cg_count, displays.data(), &cg_count);
210  Q_ASSERT(cg_count == (CGDisplayCount)displays.size());
211  for(int i = 0; i < (int)cg_count; ++i) {
212  CGRect r = CGDisplayBounds(displays.at(i));
213  w = qMax<int>(w, qRound(r.origin.x + r.size.width));
214  h = qMax<int>(h, qRound(r.origin.y + r.size.height));
215  }
216  return QSize(w, h);
217 }
218 
219 #ifdef QT_MAC_USE_COCOA
220 static NSDrawer *qt_mac_drawer_for(const QWidget *widget)
221 {
222  NSView *widgetView = reinterpret_cast<NSView *>(widget->window()->effectiveWinId());
223  NSArray *windows = [NSApp windows];
224  for (NSWindow *window in windows) {
225  NSArray *drawers = [window drawers];
226  for (NSDrawer *drawer in drawers) {
227  if ([drawer contentView] == widgetView)
228  return drawer;
229  }
230  }
231  return 0;
232 }
233 #endif
234 
236 {
237 #ifdef QT_MAC_USE_COCOA
238  NSWindow *window = [view window];
239  if ([window contentView] == view) {
240  NSView* newView = [[NSView alloc] initWithFrame:[view bounds]];
241  [window setContentView:newView];
242  [newView release];
243  } else {
244  [view removeFromSuperview];
245  [view release];
246  }
247 #else
248  HIViewRemoveFromSuperview(view);
249  CFRelease(view);
250 #endif
251 }
252 
254 {
255 #ifdef QT_MAC_USE_COCOA
256  if ([window isVisible] && [window isSheet]){
257  [NSApp endSheet:window];
258  [window orderOut:window];
259  }
260 
261  [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] resignDelegateForWindow:window];
262  [window release];
263 #else
264  // Remove property to clean up memory:
265  RemoveWindowProperty(window, kWidgetCreatorQt, kWidgetPropertyQWidget);
266  CFRelease(window);
267 #endif
268 }
269 
270 static void qt_mac_destructDrawer(NSDrawer *drawer)
271 {
272 #ifdef QT_MAC_USE_COCOA
273  [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] resignDelegateForDrawer:drawer];
274  [drawer release];
275 #else
276  Q_UNUSED(drawer);
277 #endif
278 }
279 
281 {
282  static int qt_mac_carbon_clickthrough = -1;
283  if (qt_mac_carbon_clickthrough < 0)
284  qt_mac_carbon_clickthrough = !qgetenv("QT_MAC_NO_COCOA_CLICKTHROUGH").isEmpty();
285  bool ret = !qt_mac_carbon_clickthrough;
286  for ( ; w; w = w->parentWidget()) {
288  ret = false;
289  break;
290  }
291  }
292  return ret;
293 }
294 
296 {
297  if (!w)
298  return false;
299 
300  Qt::WindowModality modality = w->windowModality();
301  if (modality == Qt::ApplicationModal)
302  return false;
303  return w->parentWidget() && (modality == Qt::WindowModal || w->windowType() == Qt::Sheet);
304 }
305 
307 {
308  return (w && w->parentWidget() && w->windowType() == Qt::Drawer);
309 }
310 
312 {
313 #ifdef QT_MAC_USE_COCOA
314  return [[reinterpret_cast<NSView *>(w->effectiveWinId()) window] isKeyWindow];
315 #else
316  Q_UNUSED(w);
317 #endif
318  return false;
319 }
320 
321 bool qt_mac_set_drawer_preferred_edge(QWidget *w, Qt::DockWidgetArea where) //users of Qt for Mac OS X can use this..
322 {
323  if(!qt_mac_is_macdrawer(w))
324  return false;
325 
326 #if QT_MAC_USE_COCOA
327  NSDrawer *drawer = qt_mac_drawer_for(w);
328  if (!drawer)
329  return false;
330  NSRectEdge edge;
331  if (where & Qt::LeftDockWidgetArea)
332  edge = NSMinXEdge;
333  else if (where & Qt::RightDockWidgetArea)
334  edge = NSMaxXEdge;
335  else if (where & Qt::TopDockWidgetArea)
336  edge = NSMaxYEdge;
337  else if (where & Qt::BottomDockWidgetArea)
338  edge = NSMinYEdge;
339  else
340  return false;
341 
342  if (edge == [drawer preferredEdge]) //no-op
343  return false;
344 
345  if (w->isVisible()) {
346  [drawer close];
347  [drawer openOnEdge:edge];
348  }
349  [drawer setPreferredEdge:edge];
350 #else
352  OptionBits edge;
353  if(where & Qt::LeftDockWidgetArea)
354  edge = kWindowEdgeLeft;
355  else if(where & Qt::RightDockWidgetArea)
356  edge = kWindowEdgeRight;
357  else if(where & Qt::TopDockWidgetArea)
358  edge = kWindowEdgeTop;
359  else if(where & Qt::BottomDockWidgetArea)
360  edge = kWindowEdgeBottom;
361  else
362  return false;
363 
364  if(edge == GetDrawerPreferredEdge(window)) //no-op
365  return false;
366 
367  //do it
368  SetDrawerPreferredEdge(window, edge);
369  if(w->isVisible()) {
370  CloseDrawer(window, false);
371  OpenDrawer(window, edge, true);
372  }
373 #endif
374  return true;
375 }
376 
377 #ifndef QT_MAC_USE_COCOA
379 #endif
381 {
382  QPoint ret = w->data->wrect.topLeft();
383  while(w && !w->isWindow()) {
384  ret += w->pos();
385  w = w->parentWidget();
386  }
387  return ret;
388 }
389 
390 //find a QWidget from a OSWindowRef
392 {
393 #ifdef QT_MAC_USE_COCOA
394  return [window QT_MANGLE_NAMESPACE(qt_qwidget)];
395 #else
396  if(!window)
397  return 0;
398 
399  QWidget *ret;
400  if(GetWindowProperty(window, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(ret), 0, &ret) == noErr)
401  return ret;
402  return 0;
403 #endif
404 }
405 
406 inline static void qt_mac_set_fullscreen_mode(bool b)
407 {
408  extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
409  if(qt_mac_app_fullscreen == b)
410  return;
411  qt_mac_app_fullscreen = b;
412  if (b) {
413  SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
414  } else {
415  SetSystemUIMode(kUIModeNormal, 0);
416  }
417 }
418 
420 {
421  return reinterpret_cast<OSViewRef>(w->internalWinId());
422 }
423 
425 {
426  // Get the first non-alien (parent) widget for
427  // w, and return its NSView (if it has one):
428  return reinterpret_cast<OSViewRef>(w->effectiveWinId());
429 }
430 
432 {
433 #ifdef QT_MAC_USE_COCOA
434  return [w contentView];
435 #else
436  HIViewRef contentView = 0;
437  OSStatus err = GetRootControl(w, &contentView); // Returns the window's content view (Apple QA1214)
438  if (err == errUnknownControl) {
439  contentView = HIViewGetRoot(w);
440  } else if (err != noErr) {
441  qWarning("Qt:Could not get content or root view of window! %s:%d [%ld]",
442  __FILE__, __LINE__, err);
443  }
444  return contentView;
445 #endif
446 }
447 
449 {
450  return widget->macEvent(0, ref);
451 }
452 
454 {
455 #ifdef QT_MAC_USE_COCOA
456  if (view)
457  return [view window];
458  return 0;
459 #else
460  return HIViewGetWindow(view);
461 #endif
462 }
463 
465 {
466 #ifdef QT_MAC_USE_COCOA
467  return [ref isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaView) class]];
468 #else
469  return HIObjectIsOfClass(HIObjectRef(ref), kObjectQWidget);
470 #endif
471 }
472 
474 {
475  if (!window)
476  return false;
477 
478  if (!window->internalWinId())
479  return true; //alien
480 
481  return qt_isGenuineQWidget(OSViewRef(window->internalWinId()));
482 }
483 
485 {
486  if (OSViewRef hiview = qt_mac_effectiveview_for(w)) {
488  if (window)
489  return window;
490 
491  if (qt_isGenuineQWidget(hiview)) {
492  // This is a workaround for NSToolbar. When a widget is hidden
493  // by clicking the toolbar button, Cocoa reparents the widgets
494  // to another window (but Qt doesn't know about it).
495  // When we start showing them, it reparents back,
496  // but at this point it's window is nil, but the window it's being brought
497  // into (the Qt one) is for sure created.
498  // This stops the hierarchy moving under our feet.
499  QWidget *toplevel = w->window();
500  if (toplevel != w) {
501  hiview = qt_mac_nativeview_for(toplevel);
502  if (OSWindowRef w = qt_mac_window_for(hiview))
503  return w;
504  }
505 
506  toplevel->d_func()->createWindow_sys();
507  // Reget the hiview since "create window" could potentially move the view (I guess).
508  hiview = qt_mac_nativeview_for(toplevel);
509  return qt_mac_window_for(hiview);
510  }
511  }
512  return 0;
513 }
514 
515 #ifndef QT_MAC_USE_COCOA
516 /* Checks if the current group is a 'stay on top' group. If so, the
517  group gets removed from the hash table */
518 static void qt_mac_release_stays_on_top_group(WindowGroupRef group)
519 {
520  for (WindowGroupHash::iterator it = qt_mac_window_groups()->begin(); it != qt_mac_window_groups()->end(); ++it) {
521  if (it.value() == group) {
522  qt_mac_window_groups()->remove(it.key());
523  return;
524  }
525  }
526 }
527 
528 /* Use this function instead of ReleaseWindowGroup, this will be sure to release the
529  stays on top window group (created with qt_mac_get_stays_on_top_group below) */
530 static void qt_mac_release_window_group(WindowGroupRef group)
531 {
532  ReleaseWindowGroup(group);
533  if (GetWindowGroupRetainCount(group) == 0)
535 }
536 #define ReleaseWindowGroup(x) Are you sure you wanted to do that? (you wanted qt_mac_release_window_group)
537 
538 SInt32 qt_mac_get_group_level(WindowClass wclass)
539 {
540  SInt32 group_level;
541  CGWindowLevel tmpLevel;
542  GetWindowGroupLevelOfType(GetWindowGroupOfClass(wclass), kWindowGroupLevelActive, &tmpLevel);
543  group_level = tmpLevel;
544  return group_level;
545 }
546 #endif
547 
548 #ifndef QT_MAC_USE_COCOA
549 static void qt_mac_set_window_group(OSWindowRef window, Qt::WindowFlags flags, int level)
550 {
551  WindowGroupRef group = 0;
552  if (qt_mac_window_groups()->contains(flags)) {
553  group = qt_mac_window_groups()->value(flags);
554  RetainWindowGroup(group);
555  } else {
556  CreateWindowGroup(kWindowActivationScopeNone, &group);
557  SetWindowGroupLevel(group, level);
558  SetWindowGroupParent(group, GetWindowGroupOfClass(kAllWindowClasses));
559  qt_mac_window_groups()->insert(flags, group);
560  }
561  SetWindowGroup(window, group);
562 }
563 
565 {
566  // We create one static stays on top window group so that
567  // all stays on top (aka popups) will fall into the same
568  // group and be able to be raise()'d with releation to one another (from
569  // within the same window group).
570  qt_mac_set_window_group(window, type|Qt::WindowStaysOnTopHint, qt_mac_get_group_level(kOverlayWindowClass));
571 }
572 
574 {
575  // Since new groups are created for 'stays on top' windows, the
576  // same must be done for tooltips. Otherwise, tooltips would be drawn
577  // below 'stays on top' widgets even tough they are on the same level.
578  // Also, add 'two' to the group level to make sure they also get on top of popups.
579  qt_mac_set_window_group(window, Qt::ToolTip, qt_mac_get_group_level(kHelpWindowClass)+2);
580 }
581 
583 {
584  // In Qt, a popup is seen as a 'stay on top' window.
585  // Since new groups are created for 'stays on top' windows, the
586  // same must be done for popups. Otherwise, popups would be drawn
587  // below 'stays on top' windows. Add 1 to get above pure stay-on-top windows.
588  qt_mac_set_window_group(window, Qt::Popup, qt_mac_get_group_level(kOverlayWindowClass)+1);
589 }
590 #endif
591 
592 inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRect &rect)
593 {
594  if (!widget)
595  return false;
596 
597 #ifndef QT_NO_GRAPHICSVIEW
598  QWidget *tlw = widget->window();
599  QWExtra *extra = qt_widget_private(tlw)->extra;
600  if (extra && extra->proxyWidget) {
601  extra->proxyWidget->update(rect.translated(widget->mapTo(tlw, QPoint())));
602  return true;
603  }
604 #endif
605 
606  return false;
607 }
608 
609 inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRegion &rgn)
610 {
611  if (!widget)
612  return false;
613 
614 #ifndef QT_NO_GRAPHICSVIEW
615  QWidget *tlw = widget->window();
616  QWExtra *extra = qt_widget_private(tlw)->extra;
617  if (extra && extra->proxyWidget) {
618  const QPoint offset(widget->mapTo(tlw, QPoint()));
619  const QVector<QRect> rects = rgn.rects();
620  for (int i = 0; i < rects.size(); ++i)
621  extra->proxyWidget->update(rects.at(i).translated(offset));
622  return true;
623  }
624 #endif
625 
626  return false;
627 }
628 
629 void QWidgetPrivate::macSetNeedsDisplay(QRegion region)
630 {
631  Q_Q(QWidget);
632 #ifndef QT_MAC_USE_COCOA
633  if (region.isEmpty())
634  HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true);
635  else if (RgnHandle rgnHandle = region.toQDRgnForUpdate_sys())
636  HIViewSetNeedsDisplayInRegion(qt_mac_nativeview_for(q), QMacSmartQuickDrawRegion(rgnHandle), true);
637  else
638  HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true); // do a complete repaint on overflow.
639 #else
640  if (NSView *nativeView = qt_mac_nativeview_for(q)) {
641  // INVARIANT: q is _not_ alien. So we can optimize a little:
642  if (region.isEmpty()) {
643  [nativeView setNeedsDisplay:YES];
644  } else {
645  QVector<QRect> rects = region.rects();
646  for (int i = 0; i<rects.count(); ++i) {
647  const QRect &rect = rects.at(i);
648  NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
649  [nativeView setNeedsDisplayInRect:nsrect];
650  }
651  }
652  } else if (QWidget *effectiveWidget = q->nativeParentWidget()) {
653  // INVARIANT: q is alien, and effectiveWidget is native.
654  if (NSView *effectiveView = qt_mac_nativeview_for(effectiveWidget)) {
655  if (region.isEmpty()) {
656  const QRect &rect = q->rect();
657  QPoint p = q->mapTo(effectiveWidget, rect.topLeft());
658  NSRect nsrect = NSMakeRect(p.x(), p.y(), rect.width(), rect.height());
659  [effectiveView setNeedsDisplayInRect:nsrect];
660  } else {
661  QVector<QRect> rects = region.rects();
662  for (int i = 0; i<rects.count(); ++i) {
663  const QRect &rect = rects.at(i);
664  QPoint p = q->mapTo(effectiveWidget, rect.topLeft());
665  NSRect nsrect = NSMakeRect(p.x(), p.y(), rect.width(), rect.height());
666  [effectiveView setNeedsDisplayInRect:nsrect];
667  }
668  }
669  }
670  }
671 #endif
672 }
673 
674 void QWidgetPrivate::macUpdateIsOpaque()
675 {
676  Q_Q(QWidget);
677  if (!q->testAttribute(Qt::WA_WState_Created))
678  return;
679 #ifndef QT_MAC_USE_COCOA
680  HIViewFeatures bits;
681  HIViewRef hiview = qt_mac_nativeview_for(q);
682  HIViewGetFeatures(hiview, &bits);
683  if ((bits & kHIViewIsOpaque) == isOpaque)
684  return;
685  if (isOpaque) {
686  HIViewChangeFeatures(hiview, kHIViewIsOpaque, 0);
687  } else {
688  HIViewChangeFeatures(hiview, 0, kHIViewIsOpaque);
689  }
690  if (q->isVisible())
691  HIViewReshapeStructure(qt_mac_nativeview_for(q));
692 #else
693  if (isRealWindow() && !q->testAttribute(Qt::WA_MacBrushedMetal)) {
694  bool opaque = isOpaque;
695  if (extra && extra->imageMask)
696  opaque = false; // we are never opaque when we have a mask.
697  [qt_mac_window_for(q) setOpaque:opaque];
698  }
699 #endif
700 }
701 #ifdef QT_MAC_USE_COCOA
702 static OSWindowRef qt_mac_create_window(QWidget *widget, WindowClass wclass,
703  NSUInteger wattr, const QRect &crect)
704 {
705  // Determine if we need to add in our "custom window" attribute. Cocoa is rather clever
706  // in deciding if we need the maximize button or not (i.e., it's resizeable, so you
707  // must need a maximize button). So, the only buttons we have control over are the
708  // close and minimize buttons. If someone wants to customize and NOT have the maximize
709  // button, then we have to do our hack. We only do it for these cases because otherwise
710  // the window looks different when activated. This "QtMacCustomizeWindow" attribute is
711  // intruding on a public space and WILL BREAK in the future.
712  // One can hope that there is a more public API available by that time.
713  Qt::WindowFlags flags = widget ? widget->windowFlags() : Qt::WindowFlags(0);
714  if ((flags & Qt::CustomizeWindowHint)) {
717  && !(flags & Qt::WindowMaximizeButtonHint))
718  wattr |= QtMacCustomizeWindow;
719  }
720 
721  // If we haven't created the desktop widget, you have to pass the rectangle
722  // in "cocoa coordinates" (i.e., top points to the lower left coordinate).
723  // Otherwise, we do the conversion for you. Since we are the only ones that
724  // create the desktop widget, this is OK (but confusing).
725  NSRect geo = NSMakeRect(crect.left(),
726  (qt_root_win != 0) ? flipYCoordinate(crect.bottom() + 1) : crect.top(),
727  crect.width(), crect.height());
730  switch (wclass) {
731  case kMovableModalWindowClass:
732  case kModalWindowClass:
733  case kSheetWindowClass:
734  case kFloatingWindowClass:
735  case kOverlayWindowClass:
736  case kHelpWindowClass: {
737  NSPanel *panel;
738  BOOL needFloating = NO;
739  BOOL worksWhenModal = widget && (widget->windowType() == Qt::Popup);
740  // Add in the extra flags if necessary.
741  switch (wclass) {
742  case kSheetWindowClass:
743  wattr |= NSDocModalWindowMask;
744  break;
745  case kFloatingWindowClass:
746  case kHelpWindowClass:
747  needFloating = YES;
748  wattr |= NSUtilityWindowMask;
749  break;
750  default:
751  break;
752  }
753  panel = [[QT_MANGLE_NAMESPACE(QCocoaPanel) alloc] QT_MANGLE_NAMESPACE(qt_initWithQWidget):widget contentRect:geo styleMask:wattr];
754  [panel setFloatingPanel:needFloating];
755  [panel setWorksWhenModal:worksWhenModal];
756  window = panel;
757  break;
758  }
759  case kDrawerWindowClass: {
760  NSDrawer *drawer = [[NSDrawer alloc] initWithContentSize:geo.size preferredEdge:NSMinXEdge];
761  [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] becomeDelegateForDrawer:drawer widget:widget];
762  QWidget *parentWidget = widget->parentWidget();
763  if (parentWidget)
764  [drawer setParentWindow:qt_mac_window_for(parentWidget)];
765  [drawer setLeadingOffset:0.0];
766  [drawer setTrailingOffset:25.0];
767  window = [[drawer contentView] window]; // Just to make sure we actually return a window
768  break;
769  }
770  default:
771  window = [[QT_MANGLE_NAMESPACE(QCocoaWindow) alloc] QT_MANGLE_NAMESPACE(qt_initWithQWidget):widget contentRect:geo styleMask:wattr];
772  break;
773  }
774  qt_syncCocoaTitleBarButtons(window, widget);
775  return window;
776 }
777 #else
778 static OSWindowRef qt_mac_create_window(QWidget *, WindowClass wclass, WindowAttributes wattr,
779  const QRect &crect)
780 {
782  Rect geo;
783  SetRect(&geo, crect.left(), crect.top(), crect.right() + 1, crect.bottom() + 1);
784  OSStatus err;
785  if(geo.right <= geo.left) geo.right = geo.left + 1;
786  if(geo.bottom <= geo.top) geo.bottom = geo.top + 1;
787  Rect null_rect;
788  SetRect(&null_rect, 0, 0, 1, 1);
789  err = CreateNewWindow(wclass, wattr, &null_rect, &window);
790  if(err == noErr) {
791  err = SetWindowBounds(window, kWindowContentRgn, &geo);
792  if(err != noErr)
793  qWarning("QWidget: Internal error (%s:%d)", __FILE__, __LINE__);
794  }
795  return window;
796 }
797 
798 #ifndef QT_NO_GESTURES
799 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
800 /* We build the release package against the 10.4 SDK.
801  So, to enable gestures for applications running on
802  10.6+, we define the missing constants here: */
803 enum {
813 };
814 #endif
815 #endif // QT_NO_GESTURES
816 
817 // window events
818 static EventTypeSpec window_events[] = {
819  { kEventClassWindow, kEventWindowClose },
820  { kEventClassWindow, kEventWindowExpanded },
821  { kEventClassWindow, kEventWindowHidden },
822  { kEventClassWindow, kEventWindowZoom },
823  { kEventClassWindow, kEventWindowZoomed },
824  { kEventClassWindow, kEventWindowCollapsed },
825  { kEventClassWindow, kEventWindowToolbarSwitchMode },
826  { kEventClassWindow, kEventWindowProxyBeginDrag },
827  { kEventClassWindow, kEventWindowProxyEndDrag },
828  { kEventClassWindow, kEventWindowResizeCompleted },
829  { kEventClassWindow, kEventWindowBoundsChanging },
830  { kEventClassWindow, kEventWindowGetRegion },
831  { kEventClassWindow, kEventWindowGetClickModality },
832  { kEventClassWindow, kEventWindowTransitionCompleted },
838  { kEventClassMouse, kEventMouseDown }
839 };
840 static EventHandlerUPP mac_win_eventUPP = 0;
841 static void cleanup_win_eventUPP()
842 {
843  DisposeEventHandlerUPP(mac_win_eventUPP);
844  mac_win_eventUPP = 0;
845 }
846 static const EventHandlerUPP make_win_eventUPP()
847 {
848  if(mac_win_eventUPP)
849  return mac_win_eventUPP;
851  return mac_win_eventUPP = NewEventHandlerUPP(QWidgetPrivate::qt_window_event);
852 }
853 OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, void *)
854 {
855  QScopedLoopLevelCounter loopLevelCounter(qApp->d_func()->threadData);
856  bool handled_event = true;
857  UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
858  switch(eclass) {
859  case kEventClassWindow: {
860  WindowRef wid = 0;
861  GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
862  sizeof(WindowRef), 0, &wid);
863  QWidget *widget = qt_mac_find_window(wid);
864  if(!widget) {
865  handled_event = false;
866  } else if(ekind == kEventWindowGetClickModality) {
867  // Carbon will send us kEventWindowGetClickModality before every
868  // mouse press / release event. By returning 'true', we tell Carbon
869  // that we would like the event target to receive the mouse event even
870  // if the target is modally shaddowed. In Qt, this makes sense when we
871  // e.g. have a popup showing, as the popup will grab the event
872  // and perhaps use it to close itself.
873  // By also setting the current modal window back into the event, we
874  // help Carbon determining which window is supposed to be raised.
875  handled_event = qApp->activePopupWidget() ? true : false;
876  } else if(ekind == kEventWindowClose) {
877  widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
879  } else if (ekind == kEventWindowTransitionCompleted) {
880  WindowTransitionAction transitionAction;
881  GetEventParameter(event, kEventParamWindowTransitionAction, typeWindowTransitionAction,
882  0, sizeof(transitionAction), 0, &transitionAction);
883  if (transitionAction == kWindowHideTransitionAction)
884  widget->hide();
885  } else if(ekind == kEventWindowExpanded) {
886  Qt::WindowStates currState = Qt::WindowStates(widget->data->window_state);
887  Qt::WindowStates newState = currState;
888  if (currState & Qt::WindowMinimized)
889  newState &= ~Qt::WindowMinimized;
890  if (!(currState & Qt::WindowActive))
891  newState |= Qt::WindowActive;
892  if (newState != currState) {
893  // newState will differ from currState if the window
894  // was expanded after clicking on the jewels (as opposed
895  // to calling QWidget::setWindowState)
896  widget->data->window_state = newState;
897  QWindowStateChangeEvent e(currState);
899  }
900 
901  QShowEvent qse;
903  } else if(ekind == kEventWindowZoom) {
904  widget->d_func()->topData()->normalGeometry = widget->geometry();
905  handled_event = false;
906  } else if(ekind == kEventWindowZoomed) {
907  WindowPartCode windowPart;
908  GetEventParameter(event, kEventParamWindowPartCode,
909  typeWindowPartCode, 0, sizeof(windowPart), 0, &windowPart);
910  if(windowPart == inZoomIn && widget->isMaximized()) {
911 
912  widget->data->window_state = widget->data->window_state & ~Qt::WindowMaximized;
913  QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state | Qt::WindowMaximized));
915  } else if(windowPart == inZoomOut && !widget->isMaximized()) {
916  widget->data->window_state = widget->data->window_state | Qt::WindowMaximized;
917  QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state
918  & ~Qt::WindowMaximized));
920  }
921  qt_button_down = 0;
922  } else if(ekind == kEventWindowCollapsed) {
923  if (!widget->isMinimized()) {
924  widget->data->window_state = widget->data->window_state | Qt::WindowMinimized;
925  QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state & ~Qt::WindowMinimized));
927  }
928 
929  // Deactivate this window:
930  if (widget->isActiveWindow() && !(widget->windowType() == Qt::Popup)) {
931  QWidget *w = 0;
932  if (widget->parentWidget())
933  w = widget->parentWidget()->window();
934  if (!w || (!w->isVisible() && !w->isMinimized())) {
935  for (WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
936  wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
937  if ((w = qt_mac_find_window(wp)))
938  break;
939  }
940  }
941  if(!(w && w->isVisible() && !w->isMinimized()))
942  qApp->setActiveWindow(0);
943  }
944 
945  //we send a hide to be like X11/Windows
946  QEvent e(QEvent::Hide);
948  qt_button_down = 0;
949  } else if(ekind == kEventWindowToolbarSwitchMode) {
951  HIToolbarRef toolbar;
952  if (GetWindowToolbar(wid, &toolbar) == noErr) {
953  if (toolbar) {
954  // Let HIToolbar do its thang, but things like the OpenGL context
955  // needs to know about it.
956  CallNextEventHandler(er, event);
958  widget->data->fstrut_dirty = true;
959  }
960  }
961  } else if(ekind == kEventWindowGetRegion) {
963  GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
964  sizeof(window), 0, &window);
965  WindowRegionCode wcode;
966  GetEventParameter(event, kEventParamWindowRegionCode, typeWindowRegionCode, 0,
967  sizeof(wcode), 0, &wcode);
968  if (wcode != kWindowOpaqueRgn){
969  // If the region is kWindowOpaqueRgn, don't call next
970  // event handler cause this will make the shadow of
971  // masked windows become offset. Unfortunately, we're not sure why.
972  CallNextEventHandler(er, event);
973  }
974  RgnHandle rgn;
975  GetEventParameter(event, kEventParamRgnHandle, typeQDRgnHandle, 0,
976  sizeof(rgn), 0, &rgn);
977 
978  if(QWidgetPrivate::qt_widget_rgn(qt_mac_find_window(window), wcode, rgn, false))
979  SetEventParameter(event, kEventParamRgnHandle, typeQDRgnHandle, sizeof(rgn), &rgn);
980  } else if(ekind == kEventWindowProxyBeginDrag) {
981  QIconDragEvent e;
983  } else if(ekind == kEventWindowResizeCompleted) {
984  // Create a mouse up event, since such an event is not send by carbon to the
985  // application event handler (while a mouse down <b>is</b> on kEventWindowResizeStarted)
986  EventRef mouseUpEvent;
987  CreateEvent(0, kEventClassMouse, kEventMouseUp, 0, kEventAttributeUserEvent, &mouseUpEvent);
988  UInt16 mbutton = kEventMouseButtonPrimary;
989  SetEventParameter(mouseUpEvent, kEventParamMouseButton, typeMouseButton, sizeof(mbutton), &mbutton);
991  GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0, sizeof(window), 0, &window);
992  Rect dragRect;
993  GetWindowBounds(window, kWindowGrowRgn, &dragRect);
994  Point pos = {dragRect.bottom, dragRect.right};
995  SetEventParameter(mouseUpEvent, kEventParamMouseLocation, typeQDPoint, sizeof(pos), &pos);
996  SendEventToApplication(mouseUpEvent);
997  ReleaseEvent(mouseUpEvent);
998  } else if(ekind == kEventWindowBoundsChanging) {
999  UInt32 flags = 0;
1000  GetEventParameter(event, kEventParamAttributes, typeUInt32, 0,
1001  sizeof(flags), 0, &flags);
1002  Rect nr;
1003  GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, 0,
1004  sizeof(nr), 0, &nr);
1005 
1006  QRect newRect(nr.left, nr.top, nr.right - nr.left, nr.bottom - nr.top);
1007 
1008  QTLWExtra * const tlwExtra = widget->d_func()->maybeTopData();
1009  if (tlwExtra && tlwExtra->isSetGeometry == 1) {
1010  widget->d_func()->setGeometry_sys_helper(newRect.left(), newRect.top(), newRect.width(), newRect.height(), tlwExtra->isMove);
1011  } else {
1012  //implicitly removes the maximized bit
1013  if((widget->data->window_state & Qt::WindowMaximized) &&
1014  IsWindowInStandardState(wid, 0, 0)) {
1015  widget->data->window_state &= ~Qt::WindowMaximized;
1016  QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state
1017  | Qt::WindowMaximized));
1019 
1020  }
1021 
1022  handled_event = false;
1023  const QRect oldRect = widget->data->crect;
1024  if((flags & kWindowBoundsChangeOriginChanged)) {
1025  if(nr.left != oldRect.x() || nr.top != oldRect.y()) {
1026  widget->data->crect.moveTo(nr.left, nr.top);
1027  QMoveEvent qme(widget->data->crect.topLeft(), oldRect.topLeft());
1028  QApplication::sendSpontaneousEvent(widget, &qme);
1029  }
1030  }
1031  if((flags & kWindowBoundsChangeSizeChanged)) {
1032  if (widget->isWindow()) {
1033  QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size());
1034  int dh = newSize.height() - newRect.height();
1035  int dw = newSize.width() - newRect.width();
1036  if (dw != 0 || dh != 0) {
1037  handled_event = true; // We want to change the bounds, so we handle the event
1038 
1039  // set the rect, so we can also do the resize down below (yes, we need to resize).
1040  newRect.setBottom(newRect.bottom() + dh);
1041  newRect.setRight(newRect.right() + dw);
1042 
1043  nr.left = newRect.x();
1044  nr.top = newRect.y();
1045  nr.right = nr.left + newRect.width();
1046  nr.bottom = nr.top + newRect.height();
1047  SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &nr);
1048  }
1049  }
1050 
1051  if (oldRect.width() != newRect.width() || oldRect.height() != newRect.height()) {
1052  widget->data->crect.setSize(newRect.size());
1053  HIRect bounds = CGRectMake(0, 0, newRect.width(), newRect.height());
1054 
1055  // If the WA_StaticContents attribute is set we can optimize the resize
1056  // by only repainting the newly exposed area. We do this by disabling
1057  // painting when setting the size of the view. The OS will invalidate
1058  // the newly exposed area for us.
1059  const bool staticContents = widget->testAttribute(Qt::WA_StaticContents);
1060  const HIViewRef view = qt_mac_nativeview_for(widget);
1061  if (staticContents)
1062  HIViewSetDrawingEnabled(view, false);
1063  HIViewSetFrame(view, &bounds);
1064  if (staticContents)
1065  HIViewSetDrawingEnabled(view, true);
1066 
1067  QResizeEvent qre(newRect.size(), oldRect.size());
1068  QApplication::sendSpontaneousEvent(widget, &qre);
1070  }
1071  }
1072  }
1073  } else if (ekind == kEventWindowHidden) {
1074  // Make sure that we also hide any visible sheets on our window.
1075  // Cocoa does the right thing for us.
1076  const QObjectList children = widget->children();
1077  const int childCount = children.count();
1078  for (int i = 0; i < childCount; ++i) {
1079  QObject *obj = children.at(i);
1080  if (obj->isWidgetType()) {
1081  QWidget *widget = static_cast<QWidget *>(obj);
1082  if (qt_mac_is_macsheet(widget) && widget->isVisible())
1083  widget->hide();
1084  }
1085  }
1086  } else {
1087  handled_event = false;
1088  }
1089  break; }
1090  case kEventClassMouse: {
1091 #if 0
1092  return SendEventToApplication(event);
1093 #endif
1094 
1095  bool send_to_app = false;
1096  {
1097  WindowPartCode wpc;
1098  if (GetEventParameter(event, kEventParamWindowPartCode, typeWindowPartCode, 0,
1099  sizeof(wpc), 0, &wpc) == noErr && wpc != inContent)
1100  send_to_app = true;
1101  }
1102  if(!send_to_app) {
1103  WindowRef window;
1104  if(GetEventParameter(event, kEventParamWindowRef, typeWindowRef, 0,
1105  sizeof(window), 0, &window) == noErr) {
1106  HIViewRef hiview;
1107  if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) {
1108  if(QWidget *w = QWidget::find((WId)hiview)) {
1109 #if 0
1110  send_to_app = !w->isActiveWindow();
1111 #else
1112  Q_UNUSED(w);
1113  send_to_app = true;
1114 #endif
1115  }
1116  }
1117  }
1118  }
1119  if(send_to_app)
1120  return SendEventToApplication(event);
1121  handled_event = false;
1122  break; }
1123 
1124 #ifndef QT_NO_GESTURES
1125  case kEventClassGesture: {
1126  // First, find the widget that was under
1127  // the mouse when the gesture happened:
1128  HIPoint screenLocation;
1129  if (GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0,
1130  sizeof(screenLocation), 0, &screenLocation) != noErr) {
1131  handled_event = false;
1132  break;
1133  }
1134  QWidget *widget = QApplication::widgetAt(screenLocation.x, screenLocation.y);
1135  if (!widget) {
1136  handled_event = false;
1137  break;
1138  }
1139 
1140  QNativeGestureEvent qNGEvent;
1141  qNGEvent.position = QPoint(screenLocation.x, screenLocation.y);
1142 
1143  switch (ekind) {
1144  case kEventGestureStarted:
1146  break;
1147  case kEventGestureEnded:
1149  break;
1150  case kEventGestureRotate: {
1151  CGFloat amount;
1152  if (GetEventParameter(event, kEventParamRotationAmount, 'cgfl', 0,
1153  sizeof(amount), 0, &amount) != noErr) {
1154  handled_event = false;
1155  break;
1156  }
1158  qNGEvent.percentage = float(-amount);
1159  break; }
1160  case kEventGestureSwipe: {
1161  HIPoint swipeDirection;
1162  if (GetEventParameter(event, kEventParamSwipeDirection, typeHIPoint, 0,
1163  sizeof(swipeDirection), 0, &swipeDirection) != noErr) {
1164  handled_event = false;
1165  break;
1166  }
1168  if (swipeDirection.x == 1)
1169  qNGEvent.angle = 180.0f;
1170  else if (swipeDirection.x == -1)
1171  qNGEvent.angle = 0.0f;
1172  else if (swipeDirection.y == 1)
1173  qNGEvent.angle = 90.0f;
1174  else if (swipeDirection.y == -1)
1175  qNGEvent.angle = 270.0f;
1176  break; }
1177  case kEventGestureMagnify: {
1178  CGFloat amount;
1179  if (GetEventParameter(event, kEventParamMagnificationAmount, 'cgfl', 0,
1180  sizeof(amount), 0, &amount) != noErr) {
1181  handled_event = false;
1182  break;
1183  }
1185  qNGEvent.percentage = float(amount);
1186  break; }
1187  }
1188 
1189  QApplication::sendSpontaneousEvent(widget, &qNGEvent);
1190  break; }
1191 #endif // QT_NO_GESTURES
1192 
1193  default:
1194  handled_event = false;
1195  }
1196  if(!handled_event) //let the event go through
1197  return eventNotHandledErr;
1198  return noErr; //we eat the event
1199 }
1200 
1201 // widget events
1202 static HIObjectClassRef widget_class = 0;
1203 static EventTypeSpec widget_events[] = {
1204  { kEventClassHIObject, kEventHIObjectConstruct },
1205  { kEventClassHIObject, kEventHIObjectDestruct },
1206 
1207  { kEventClassControl, kEventControlDraw },
1208  { kEventClassControl, kEventControlInitialize },
1209  { kEventClassControl, kEventControlGetPartRegion },
1210  { kEventClassControl, kEventControlGetClickActivation },
1211  { kEventClassControl, kEventControlSetFocusPart },
1212  { kEventClassControl, kEventControlDragEnter },
1213  { kEventClassControl, kEventControlDragWithin },
1214  { kEventClassControl, kEventControlDragLeave },
1215  { kEventClassControl, kEventControlDragReceive },
1216  { kEventClassControl, kEventControlOwningWindowChanged },
1217  { kEventClassControl, kEventControlBoundsChanged },
1218  { kEventClassControl, kEventControlGetSizeConstraints },
1219  { kEventClassControl, kEventControlVisibilityChanged },
1220 
1221  { kEventClassMouse, kEventMouseDown },
1222  { kEventClassMouse, kEventMouseUp },
1223  { kEventClassMouse, kEventMouseMoved },
1224  { kEventClassMouse, kEventMouseDragged }
1225 };
1226 static EventHandlerUPP mac_widget_eventUPP = 0;
1228 {
1229  DisposeEventHandlerUPP(mac_widget_eventUPP);
1230  mac_widget_eventUPP = 0;
1231 }
1232 static const EventHandlerUPP make_widget_eventUPP()
1233 {
1235  return mac_widget_eventUPP;
1237  return mac_widget_eventUPP = NewEventHandlerUPP(QWidgetPrivate::qt_widget_event);
1238 }
1239 OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, void *)
1240 {
1242 
1243  bool handled_event = true;
1244  UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
1245  switch(eclass) {
1246  case kEventClassHIObject: {
1247  HIViewRef view = 0;
1248  GetEventParameter(event, kEventParamHIObjectInstance, typeHIObjectRef,
1249  0, sizeof(view), 0, &view);
1250  if(ekind == kEventHIObjectConstruct) {
1251  if(view) {
1252  HIViewChangeFeatures(view, kHIViewAllowsSubviews, 0);
1253  SetEventParameter(event, kEventParamHIObjectInstance,
1254  typeVoidPtr, sizeof(view), &view);
1255  }
1256  } else if(ekind == kEventHIObjectDestruct) {
1257  //nothing to really do.. or is there?
1258  } else {
1259  handled_event = false;
1260  }
1261  break; }
1262  case kEventClassControl: {
1263  QWidget *widget = 0;
1264  HIViewRef hiview = 0;
1265  if(GetEventParameter(event, kEventParamDirectObject, typeControlRef,
1266  0, sizeof(hiview), 0, &hiview) == noErr)
1267  widget = QWidget::find((WId)hiview);
1268  if (widget && widget->macEvent(er, event))
1269  return noErr;
1270  if(ekind == kEventControlDraw) {
1271  if(widget && qt_isGenuineQWidget(hiview)) {
1272 
1273  // if there is a window change event pending for any gl child wigets,
1274  // send it immediately. (required for flicker-free resizing)
1275  extern void qt_mac_send_posted_gl_updates(QWidget *widget);
1277 
1278  if (QApplicationPrivate::graphicsSystem() && !widget->d_func()->paintOnScreen()) {
1279  widget->d_func()->syncBackingStore();
1280  widget->d_func()->dirtyOnWidget = QRegion();
1281  return noErr;
1282  }
1283 
1284  //requested rgn
1285  RgnHandle rgn;
1286  GetEventParameter(event, kEventParamRgnHandle, typeQDRgnHandle, 0, sizeof(rgn), 0, &rgn);
1288 
1289  //update handles
1290  GrafPtr qd = 0;
1291  CGContextRef cg = 0;
1292  if(GetEventParameter(event, kEventParamCGContextRef, typeCGContextRef, 0, sizeof(cg), 0, &cg) != noErr) {
1293  Q_ASSERT(false);
1294  }
1295  widget->d_func()->hd = cg;
1296  widget->d_func()->qd_hd = qd;
1297  CGContextSaveGState(cg);
1298 
1299 #ifdef DEBUG_WIDGET_PAINT
1300  const bool doDebug = true;
1301  if(doDebug) {
1302  qDebug("asked to draw %p[%p] [%s::%s] %p[%p] [%d] [%dx%d]", widget, hiview, widget->metaObject()->className(),
1303  widget->objectName().local8Bit().data(), widget->parentWidget(),
1304  (HIViewRef)(widget->parentWidget() ? qt_mac_nativeview_for(widget->parentWidget()) : (HIViewRef)0),
1305  HIViewIsCompositingEnabled(hiview), qt_mac_posInWindow(widget).x(), qt_mac_posInWindow(widget).y());
1306 #if 0
1307  QVector<QRect> region_rects = qrgn.rects();
1308  qDebug("Region! %d", region_rects.count());
1309  for(int i = 0; i < region_rects.count(); i++)
1310  qDebug("%d %d %d %d", region_rects[i].x(), region_rects[i].y(),
1311  region_rects[i].width(), region_rects[i].height());
1312  region_rects = widget->d_func()->clp.rects();
1313  qDebug("Widget Region! %d", region_rects.count());
1314  for(int i = 0; i < region_rects.count(); i++)
1315  qDebug("%d %d %d %d", region_rects[i].x(), region_rects[i].y(),
1316  region_rects[i].width(), region_rects[i].height());
1317 #endif
1318  }
1319 #endif
1320  if (widget->isVisible() && widget->updatesEnabled()) { //process the actual paint event.
1322  qWarning("QWidget::repaint: Recursive repaint detected");
1323  if (widget->isWindow() && !widget->d_func()->isOpaque
1324  && !widget->testAttribute(Qt::WA_MacBrushedMetal)) {
1325  QRect qrgnRect = qrgn.boundingRect();
1326  CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height()));
1327  }
1328 
1329  QPoint redirectionOffset(0, 0);
1330  QWidget *tl = widget->window();
1331  if (tl) {
1332  Qt::WindowFlags flags = tl->windowFlags();
1333  if (flags & Qt::FramelessWindowHint
1334  || (flags & Qt::CustomizeWindowHint && !(flags & Qt::WindowTitleHint))) {
1335  if(tl->d_func()->extra && !tl->d_func()->extra->mask.isEmpty())
1336  redirectionOffset += tl->d_func()->extra->mask.boundingRect().topLeft();
1337  }
1338  }
1339 
1340  //setup the context
1342  QPaintEngine *engine = widget->paintEngine();
1343  if (engine)
1344  engine->setSystemClip(qrgn);
1345 
1346  //handle the erase
1347  if (engine && (!widget->testAttribute(Qt::WA_NoSystemBackground)
1348  && (widget->isWindow() || widget->autoFillBackground())
1350  || widget->testAttribute(Qt::WA_StyledBackground))) {
1351 #ifdef DEBUG_WIDGET_PAINT
1352  if(doDebug)
1353  qDebug(" Handling erase for [%s::%s]", widget->metaObject()->className(),
1354  widget->objectName().local8Bit().data());
1355 #endif
1356  if (!redirectionOffset.isNull())
1357  widget->d_func()->setRedirected(widget, redirectionOffset);
1358 
1359  bool was_unclipped = widget->testAttribute(Qt::WA_PaintUnclipped);
1360  widget->setAttribute(Qt::WA_PaintUnclipped, false);
1361  QPainter p(widget);
1362  p.setClipping(false);
1363  if(was_unclipped)
1365  widget->d_func()->paintBackground(&p, qrgn, widget->isWindow() ? DrawAsRoot : 0);
1366  if (widget->testAttribute(Qt::WA_TintedBackground)) {
1367  QColor tint = widget->palette().window().color();
1368  tint.setAlphaF(.6);
1369  const QVector<QRect> &rects = qrgn.rects();
1370  for (int i = 0; i < rects.size(); ++i)
1371  p.fillRect(rects.at(i), tint);
1372  }
1373  p.end();
1374  if (!redirectionOffset.isNull())
1375  widget->d_func()->restoreRedirected();
1376  }
1377 
1378  if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
1379  CallNextEventHandler(er, event);
1380 
1381  //send the paint
1382  redirectionOffset += widget->data->wrect.topLeft(); // Map from system to qt coordinates
1383  if (!redirectionOffset.isNull())
1384  widget->d_func()->setRedirected(widget, redirectionOffset);
1385  qrgn.translate(redirectionOffset);
1386  QPaintEvent e(qrgn);
1387  widget->d_func()->dirtyOnWidget = QRegion();
1388 #ifdef QT3_SUPPORT
1389  e.setErased(true);
1390 #endif
1392  if (!redirectionOffset.isNull())
1393  widget->d_func()->restoreRedirected();
1394 
1395  //cleanup
1396  if (engine)
1397  engine->setSystemClip(QRegion());
1398 
1399  widget->setAttribute(Qt::WA_WState_InPaintEvent, false);
1401  qWarning("QWidget: It is dangerous to leave painters active on a widget outside of the PaintEvent");
1402  }
1403 
1404  widget->d_func()->hd = 0;
1405  widget->d_func()->qd_hd = 0;
1406  CGContextRestoreGState(cg);
1407  } else if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget)) {
1408  CallNextEventHandler(er, event);
1409  }
1410  } else if(ekind == kEventControlInitialize) {
1411  if(HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget)) {
1412  UInt32 features = kControlSupportsDragAndDrop | kControlSupportsClickActivation | kControlSupportsFocus;
1413  SetEventParameter(event, kEventParamControlFeatures, typeUInt32, sizeof(features), &features);
1414  } else {
1415  handled_event = false;
1416  }
1417  } else if(ekind == kEventControlSetFocusPart) {
1418  if(widget) {
1419  ControlPartCode part;
1420  GetEventParameter(event, kEventParamControlPart, typeControlPartCode, 0,
1421  sizeof(part), 0, &part);
1422  if(part == kControlFocusNoPart){
1423  if (widget->hasFocus())
1425  } else
1426  widget->setFocus();
1427  }
1428  if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
1429  CallNextEventHandler(er, event);
1430  } else if(ekind == kEventControlGetClickActivation) {
1431  ClickActivationResult clickT = kActivateAndIgnoreClick;
1432  SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult,
1433  sizeof(clickT), &clickT);
1434  } else if(ekind == kEventControlGetPartRegion) {
1435  handled_event = false;
1436  if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget) && CallNextEventHandler(er, event) == noErr) {
1437  handled_event = true;
1438  break;
1439  }
1440  if(widget && !widget->isWindow()) {
1441  ControlPartCode part;
1442  GetEventParameter(event, kEventParamControlPart, typeControlPartCode, 0,
1443  sizeof(part), 0, &part);
1444  if(part == kControlClickableMetaPart && widget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
1445  RgnHandle rgn;
1446  GetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle, 0,
1447  sizeof(rgn), 0, &rgn);
1448  SetEmptyRgn(rgn);
1449  handled_event = true;
1450  } else if(part == kControlStructureMetaPart || part == kControlClickableMetaPart) {
1451  RgnHandle rgn;
1452  GetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle, 0,
1453  sizeof(rgn), 0, &rgn);
1454  SetRectRgn(rgn, 0, 0, widget->width(), widget->height());
1455  if(QWidgetPrivate::qt_widget_rgn(widget, kWindowStructureRgn, rgn, false))
1456  handled_event = true;
1457  } else if(part == kControlOpaqueMetaPart) {
1458  if(widget->d_func()->isOpaque) {
1459  RgnHandle rgn;
1460  GetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle, 0,
1461  sizeof(RgnHandle), 0, &rgn);
1462  SetRectRgn(rgn, 0, 0, widget->width(), widget->height());
1463  QWidgetPrivate::qt_widget_rgn(widget, kWindowStructureRgn, rgn, false);
1464  SetEventParameter(event, kEventParamControlRegion, typeQDRgnHandle,
1465  sizeof(RgnHandle), &rgn);
1466  handled_event = true;
1467  }
1468  }
1469  }
1470  } else if(ekind == kEventControlOwningWindowChanged) {
1471  if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
1472  CallNextEventHandler(er, event);
1473  if(widget && qt_mac_window_for(hiview)) {
1474  WindowRef foo = 0;
1475  GetEventParameter(event, kEventParamControlCurrentOwningWindow, typeWindowRef, 0,
1476  sizeof(foo), 0, &foo);
1477  widget->d_func()->initWindowPtr();
1478  }
1479  if (widget)
1481  } else if(ekind == kEventControlDragEnter || ekind == kEventControlDragWithin ||
1482  ekind == kEventControlDragLeave || ekind == kEventControlDragReceive) {
1483  // dnd are really handled in qdnd_mac.cpp,
1484  // just modularize the code a little...
1485  DragRef drag;
1486  GetEventParameter(event, kEventParamDragRef, typeDragRef, 0, sizeof(drag), 0, &drag);
1487  handled_event = false;
1488  bool drag_allowed = false;
1489 
1491  if (qobject_cast<QFocusFrame *>(widget)){
1492  // We might shadow widgets underneath the focus
1493  // frame, so stay interrested, and let the dnd through
1494  drag_allowed = true;
1495  handled_event = true;
1496  Point where;
1497  GetDragMouse(drag, &where, 0);
1498  dropWidget = QApplication::widgetAt(QPoint(where.h, where.v));
1499 
1500  if (dropWidget != QDragManager::self()->currentTarget()) {
1501  // We have to 'fake' enter and leave events for the shaddowed widgets:
1502  if (ekind == kEventControlDragEnter) {
1503  if (QDragManager::self()->currentTarget())
1504  QDragManager::self()->currentTarget()->d_func()->qt_mac_dnd_event(kEventControlDragLeave, drag);
1505  if (dropWidget) {
1506  dropWidget->d_func()->qt_mac_dnd_event(kEventControlDragEnter, drag);
1507  }
1508  // Set dropWidget to zero, so qt_mac_dnd_event
1509  // doesn't get called a second time below:
1510  dropWidget = 0;
1511  } else if (ekind == kEventControlDragLeave) {
1512  dropWidget = QDragManager::self()->currentTarget();
1513  if (dropWidget) {
1514  dropWidget->d_func()->qt_mac_dnd_event(kEventControlDragLeave, drag);
1515  }
1516  // Set dropWidget to zero, so qt_mac_dnd_event
1517  // doesn't get called a second time below:
1518  dropWidget = 0;
1519  }
1520  }
1521  }
1522 
1523  // Send the dnd event to the widget:
1524  if (dropWidget && dropWidget->d_func()->qt_mac_dnd_event(ekind, drag)) {
1525  drag_allowed = true;
1526  handled_event = true;
1527  }
1528 
1529  if (ekind == kEventControlDragEnter) {
1530  // If we don't accept the enter event, we will
1531  // receive no more drag events for this widget
1532  const Boolean wouldAccept = drag_allowed ? true : false;
1533  SetEventParameter(event, kEventParamControlWouldAcceptDrop, typeBoolean,
1534  sizeof(wouldAccept), &wouldAccept);
1535  }
1536  } else if (ekind == kEventControlBoundsChanged) {
1537  if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_Moved) || widget->testAttribute(Qt::WA_Resized)) {
1538  handled_event = false;
1539  } else {
1540  // Sync our view in case some other (non-Qt) view is controlling us.
1541  handled_event = true;
1542  Rect newBounds;
1543  GetEventParameter(event, kEventParamCurrentBounds,
1544  typeQDRectangle, 0, sizeof(Rect), 0, &newBounds);
1545  QRect rect(newBounds.left, newBounds.top,
1546  newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
1547 
1548  bool moved = widget->testAttribute(Qt::WA_Moved);
1549  bool resized = widget->testAttribute(Qt::WA_Resized);
1550  widget->setGeometry(rect);
1551  widget->setAttribute(Qt::WA_Moved, moved);
1552  widget->setAttribute(Qt::WA_Resized, resized);
1554  }
1555  } else if (ekind == kEventControlGetSizeConstraints) {
1556  if (!widget || !qt_isGenuineQWidget(widget)) {
1557  handled_event = false;
1558  } else {
1559  handled_event = true;
1560  QWidgetItem item(widget);
1561  QSize size = item.minimumSize();
1562  HISize hisize = { size.width(), size.height() };
1563  SetEventParameter(event, kEventParamMinimumSize, typeHISize, sizeof(HISize), &hisize);
1564  size = item.maximumSize();
1565  hisize.width = size.width() + 2; // ### shouldn't have to add 2 (but it works).
1566  hisize.height = size.height();
1567  SetEventParameter(event, kEventParamMaximumSize, typeHISize, sizeof(HISize), &hisize);
1568  }
1569  } else if (ekind == kEventControlVisibilityChanged) {
1570  handled_event = false;
1571  if (widget) {
1573  if (!HIViewIsVisible(HIViewRef(widget->winId()))) {
1574  if (widget == qt_button_down)
1575  qt_button_down = 0;
1576  }
1577  }
1578  }
1579  break; }
1580  case kEventClassMouse: {
1581  bool send_to_app = false;
1582  if(qt_button_down)
1583  send_to_app = true;
1584  if(send_to_app) {
1585  OSStatus err = SendEventToApplication(event);
1586  if(err != noErr)
1587  handled_event = false;
1588  } else {
1589  CallNextEventHandler(er, event);
1590  }
1591  break; }
1592  default:
1593  handled_event = false;
1594  break;
1595  }
1596  if(!handled_event) //let the event go through
1597  return eventNotHandledErr;
1598  return noErr; //we eat the event
1599 }
1600 #endif
1601 
1603 {
1604 #ifdef QT_MAC_USE_COCOA
1606  QT_MANGLE_NAMESPACE(QCocoaView) *view = [[QT_MANGLE_NAMESPACE(QCocoaView) alloc] initWithQWidget:widget widgetPrivate:widgetPrivate];
1607 
1608 #ifdef ALIEN_DEBUG
1609  qDebug() << "Creating NSView for" << widget;
1610 #endif
1611 
1612  if (view && parent)
1613  [parent addSubview:view];
1614  return view;
1615 #else
1616  Q_UNUSED(widget);
1617  Q_UNUSED(widgetPrivate);
1618  if(!widget_class) {
1619  OSStatus err = HIObjectRegisterSubclass(kObjectQWidget, kHIViewClassID, 0, make_widget_eventUPP(),
1620  GetEventTypeCount(widget_events), widget_events,
1621  0, &widget_class);
1622  if (err && err != hiObjectClassExistsErr)
1623  qWarning("QWidget: Internal error (%d)", __LINE__);
1624  }
1625  HIViewRef ret = 0;
1626  if(HIObjectCreate(kObjectQWidget, 0, (HIObjectRef*)&ret) != noErr)
1627  qWarning("QWidget: Internal error (%d)", __LINE__);
1628  if(ret && parent)
1629  HIViewAddSubview(parent, ret);
1630  return ret;
1631 #endif
1632 }
1633 
1635 {
1636 #ifndef QT_MAC_USE_COCOA
1637  HIObjectUnregisterClass(widget_class);
1638  widget_class = 0;
1639 #endif
1640 }
1641 
1642 void QWidgetPrivate::toggleDrawers(bool visible)
1643 {
1644  for (int i = 0; i < children.size(); ++i) {
1645  register QObject *object = children.at(i);
1646  if (!object->isWidgetType())
1647  continue;
1648  QWidget *widget = static_cast<QWidget*>(object);
1649  if(qt_mac_is_macdrawer(widget)) {
1650  bool oldState = widget->testAttribute(Qt::WA_WState_ExplicitShowHide);
1651  if(visible) {
1653  widget->show();
1654  } else {
1655  widget->hide();
1656  if(!oldState)
1658  }
1659  }
1660  }
1661 }
1662 
1663 /*****************************************************************************
1664  QWidgetPrivate member functions
1665  *****************************************************************************/
1666 bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up)
1667 {
1668  // I'm not sure what "up" is
1669  if(!w || !w->isWindow())
1670  return false;
1671 
1672  QTLWExtra *topData = w->d_func()->topData();
1673  QWExtra *extraData = w->d_func()->extraData();
1674  // topData->resizer is only 4 bits, so subtracting -1 from zero causes bad stuff
1675  // to happen, prevent that here (you really want the thing hidden).
1676  if (up >= 0 || topData->resizer != 0)
1677  topData->resizer += up;
1679  {
1680 #ifndef QT_MAC_USE_COCOA
1681  WindowClass wclass;
1682  GetWindowClass(windowRef, &wclass);
1683  if(!(GetAvailableWindowAttributes(wclass) & kWindowResizableAttribute))
1684  return true;
1685 #endif
1686  }
1687  bool remove_grip = (topData->resizer || (w->windowFlags() & Qt::FramelessWindowHint)
1688  || (extraData->maxw && extraData->maxh &&
1689  extraData->maxw == extraData->minw && extraData->maxh == extraData->minh));
1690 #ifndef QT_MAC_USE_COCOA
1691  WindowAttributes attr;
1692  GetWindowAttributes(windowRef, &attr);
1693  if(remove_grip) {
1694  if(attr & kWindowResizableAttribute) {
1695  ChangeWindowAttributes(qt_mac_window_for(w), kWindowNoAttributes,
1696  kWindowResizableAttribute);
1697  ReshapeCustomWindow(qt_mac_window_for(w));
1698  }
1699  } else if(!(attr & kWindowResizableAttribute)) {
1700  ChangeWindowAttributes(windowRef, kWindowResizableAttribute,
1701  kWindowNoAttributes);
1702  ReshapeCustomWindow(windowRef);
1703  }
1704 #else
1705  [windowRef setShowsResizeIndicator:!remove_grip];
1706 #endif
1707  return true;
1708 }
1709 
1710 void QWidgetPrivate::qt_clean_root_win()
1711 {
1712 #ifdef QT_MAC_USE_COCOA
1714  [qt_root_win release];
1715 #else
1716  if(!qt_root_win)
1717  return;
1718  CFRelease(qt_root_win);
1719 #endif
1720  qt_root_win = 0;
1721 }
1722 
1723 bool QWidgetPrivate::qt_create_root_win()
1724 {
1725  if(qt_root_win)
1726  return false;
1727  const QSize desktopSize = qt_mac_desktopSize();
1728  QRect desktopRect(QPoint(0, 0), desktopSize);
1729 #ifdef QT_MAC_USE_COCOA
1730  qt_root_win = qt_mac_create_window(0, kOverlayWindowClass, NSBorderlessWindowMask, desktopRect);
1731 #else
1732  WindowAttributes wattr = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute);
1733  qt_root_win = qt_mac_create_window(0, kOverlayWindowClass, wattr, desktopRect);
1734 #endif
1735  if(!qt_root_win)
1736  return false;
1737  qAddPostRoutine(qt_clean_root_win);
1738  return true;
1739 }
1740 
1741 bool QWidgetPrivate::qt_widget_rgn(QWidget *widget, short wcode, RgnHandle rgn, bool force = false)
1742 {
1743  bool ret = false;
1744 #ifndef QT_MAC_USE_COCOA
1745  switch(wcode) {
1746  case kWindowStructureRgn: {
1747  if(widget) {
1748  if(widget->d_func()->extra && !widget->d_func()->extra->mask.isEmpty()) {
1750  if(!rin.isEmpty()) {
1751  QPoint rin_tl = rin.boundingRect().topLeft(); //in offset
1752  rin.translate(-rin_tl.x(), -rin_tl.y()); //bring into same space as below
1753  QRegion mask = widget->d_func()->extra->mask;
1754  Qt::WindowFlags flags = widget->windowFlags();
1755  if(widget->isWindow()
1756  && !(flags & Qt::FramelessWindowHint
1757  || (flags & Qt::CustomizeWindowHint && !(flags & Qt::WindowTitleHint)))) {
1758  QRegion title;
1759  {
1761  GetWindowRegion(qt_mac_window_for(widget), kWindowTitleBarRgn, rgn);
1762  title = qt_mac_convert_mac_region(rgn);
1763  }
1764  QRect br = title.boundingRect();
1765  mask.translate(0, br.height()); //put the mask 'under' the title bar..
1766  title.translate(-br.x(), -br.y());
1767  mask += title;
1768  }
1769 
1770  QRegion cr = rin & mask;
1771  cr.translate(rin_tl.x(), rin_tl.y()); //translate back to incoming space
1772  CopyRgn(QMacSmartQuickDrawRegion(cr.toQDRgn()), rgn);
1773  }
1774  ret = true;
1775  } else if(force) {
1776  QRegion cr(widget->geometry());
1777  CopyRgn(QMacSmartQuickDrawRegion(cr.toQDRgn()), rgn);
1778  ret = true;
1779  }
1780  }
1781  break; }
1782  default: break;
1783  }
1784  //qDebug() << widget << ret << wcode << qt_mac_convert_mac_region(rgn);
1785 #else
1786  Q_UNUSED(widget);
1787  Q_UNUSED(wcode);
1788  Q_UNUSED(rgn);
1789  Q_UNUSED(force);
1790 #endif
1791  return ret;
1792 }
1793 
1794 /*****************************************************************************
1795  QWidget member functions
1796  *****************************************************************************/
1797 void QWidgetPrivate::determineWindowClass()
1798 {
1799  Q_Q(QWidget);
1800 #if !defined(QT_NO_MAINWINDOW) && !defined(QT_NO_TOOLBAR)
1801  // Make sure that QMainWindow has the MacWindowToolBarButtonHint when the
1802  // unifiedTitleAndToolBarOnMac property is ON. This is to avoid reentry of
1803  // setParent() triggered by the QToolBar::event(QEvent::ParentChange).
1804  QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q);
1805  if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) {
1807  }
1808 #endif
1809 #ifndef QT_MAC_USE_COCOA
1810 // ### COCOA:Interleave these better!
1811 
1812  const Qt::WindowType type = q->windowType();
1813  Qt::WindowFlags &flags = data.window_flags;
1814  const bool popup = (type == Qt::Popup);
1815  if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
1816  flags |= Qt::FramelessWindowHint;
1817 
1818  WindowClass wclass = kSheetWindowClass;
1819  if(qt_mac_is_macdrawer(q))
1820  wclass = kDrawerWindowClass;
1821  else if (q->testAttribute(Qt::WA_ShowModal) && flags & Qt::CustomizeWindowHint)
1822  wclass = kDocumentWindowClass;
1823  else if(popup || (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && type == Qt::SplashScreen))
1824  wclass = kModalWindowClass;
1825  else if(q->testAttribute(Qt::WA_ShowModal))
1826  wclass = kMovableModalWindowClass;
1827  else if(type == Qt::ToolTip)
1828  wclass = kHelpWindowClass;
1830  && type == Qt::SplashScreen))
1831  wclass = kFloatingWindowClass;
1832  else
1833  wclass = kDocumentWindowClass;
1834 
1835  WindowGroupRef grp = 0;
1836  WindowAttributes wattr = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute);
1837  if (q->testAttribute(Qt::WA_MacFrameworkScaled))
1838  wattr |= kWindowFrameworkScaledAttribute;
1839  if(qt_mac_is_macsheet(q)) {
1840  //grp = GetWindowGroupOfClass(kMovableModalWindowClass);
1841  wclass = kSheetWindowClass;
1842  } else {
1843  grp = GetWindowGroupOfClass(wclass);
1844  // Shift things around a bit to get the correct window class based on the presence
1845  // (or lack) of the border.
1846  bool customize = flags & Qt::CustomizeWindowHint;
1847  bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
1848  if (framelessWindow) {
1849  if(wclass == kDocumentWindowClass) {
1850  wattr |= kWindowNoTitleBarAttribute;
1851  } else if(wclass == kFloatingWindowClass) {
1852  wattr |= kWindowNoTitleBarAttribute;
1853  } else if (wclass == kMovableModalWindowClass) {
1854  wclass = kModalWindowClass;
1855  }
1856  } else {
1857  if(wclass != kModalWindowClass)
1858  wattr |= kWindowResizableAttribute;
1859  }
1860  // Only add extra decorations (well, buttons) for widgets that can have them
1861  // and have an actual border we can put them on.
1862  if(wclass != kModalWindowClass && wclass != kMovableModalWindowClass
1863  && wclass != kSheetWindowClass && wclass != kPlainWindowClass
1864  && !framelessWindow && wclass != kDrawerWindowClass
1865  && wclass != kHelpWindowClass) {
1866  if (flags & Qt::WindowMaximizeButtonHint)
1867  wattr |= kWindowFullZoomAttribute;
1868  if (flags & Qt::WindowMinimizeButtonHint)
1869  wattr |= kWindowCollapseBoxAttribute;
1870  if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
1871  wattr |= kWindowCloseBoxAttribute;
1872  if (flags & Qt::MacWindowToolBarButtonHint)
1873  wattr |= kWindowToolbarButtonAttribute;
1874  } else {
1875  // Clear these hints so that we aren't call them on invalid windows
1878  }
1879  }
1880  if((popup || type == Qt::Tool) && !q->isModal())
1881  wattr |= kWindowHideOnSuspendAttribute;
1882  wattr |= kWindowLiveResizeAttribute;
1883 
1884 #ifdef DEBUG_WINDOW_CREATE
1885 #define ADD_DEBUG_WINDOW_NAME(x) { x, #x }
1886  struct {
1887  UInt32 tag;
1888  const char *name;
1889  } known_attribs[] = {
1890  ADD_DEBUG_WINDOW_NAME(kWindowCompositingAttribute),
1891  ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
1892  ADD_DEBUG_WINDOW_NAME(kWindowMetalAttribute),
1893  ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
1894  ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
1895  ADD_DEBUG_WINDOW_NAME(kWindowCollapseBoxAttribute),
1896  ADD_DEBUG_WINDOW_NAME(kWindowHorizontalZoomAttribute),
1897  ADD_DEBUG_WINDOW_NAME(kWindowVerticalZoomAttribute),
1898  ADD_DEBUG_WINDOW_NAME(kWindowResizableAttribute),
1899  ADD_DEBUG_WINDOW_NAME(kWindowNoActivatesAttribute),
1900  ADD_DEBUG_WINDOW_NAME(kWindowNoUpdatesAttribute),
1901  ADD_DEBUG_WINDOW_NAME(kWindowOpaqueForEventsAttribute),
1902  ADD_DEBUG_WINDOW_NAME(kWindowLiveResizeAttribute),
1903  ADD_DEBUG_WINDOW_NAME(kWindowCloseBoxAttribute),
1904  ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
1905  { 0, 0 }
1906  }, known_classes[] = {
1907  ADD_DEBUG_WINDOW_NAME(kHelpWindowClass),
1908  ADD_DEBUG_WINDOW_NAME(kPlainWindowClass),
1909  ADD_DEBUG_WINDOW_NAME(kDrawerWindowClass),
1910  ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
1911  ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
1912  ADD_DEBUG_WINDOW_NAME(kSheetWindowClass),
1913  ADD_DEBUG_WINDOW_NAME(kFloatingWindowClass),
1914  ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
1915  ADD_DEBUG_WINDOW_NAME(kDocumentWindowClass),
1916  ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
1917  ADD_DEBUG_WINDOW_NAME(kMovableModalWindowClass),
1918  ADD_DEBUG_WINDOW_NAME(kModalWindowClass),
1919  { 0, 0 }
1920  };
1921  qDebug("Qt: internal: ************* Creating new window %p (%s::%s)", q, q->metaObject()->className(),
1922  q->objectName().toLocal8Bit().constData());
1923  bool found_class = false;
1924  for(int i = 0; known_classes[i].name; i++) {
1925  if(wclass == known_classes[i].tag) {
1926  found_class = true;
1927  qDebug("Qt: internal: ** Class: %s", known_classes[i].name);
1928  break;
1929  }
1930  }
1931  if(!found_class)
1932  qDebug("Qt: internal: !! Class: Unknown! (%d)", (int)wclass);
1933  if(wattr) {
1934  WindowAttributes tmp_wattr = wattr;
1935  qDebug("Qt: internal: ** Attributes:");
1936  for(int i = 0; tmp_wattr && known_attribs[i].name; i++) {
1937  if((tmp_wattr & known_attribs[i].tag) == known_attribs[i].tag) {
1938  tmp_wattr ^= known_attribs[i].tag;
1939  qDebug("Qt: internal: * %s %s", known_attribs[i].name,
1940  (GetAvailableWindowAttributes(wclass) & known_attribs[i].tag) ? "" : "(*)");
1941  }
1942  }
1943  if(tmp_wattr)
1944  qDebug("Qt: internal: !! Attributes: Unknown (%d)", (int)tmp_wattr);
1945  }
1946 #endif
1947 
1948  /* Just to be extra careful we will change to the kUtilityWindowClass if the
1949  requested attributes cannot be used */
1950  if((GetAvailableWindowAttributes(wclass) & wattr) != wattr) {
1951  WindowClass tmp_class = wclass;
1952  if(wclass == kToolbarWindowClass || wclass == kUtilityWindowClass)
1953  wclass = kFloatingWindowClass;
1954  if(tmp_class != wclass) {
1955  if(!grp)
1956  grp = GetWindowGroupOfClass(wclass);
1957  wclass = tmp_class;
1958  }
1959  }
1960  topData()->wclass = wclass;
1961  topData()->wattr = wattr;
1962 #else
1963  const Qt::WindowType type = q->windowType();
1964  Qt::WindowFlags &flags = data.window_flags;
1965  const bool popup = (type == Qt::Popup);
1966  if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
1967  flags |= Qt::FramelessWindowHint;
1968 
1969  WindowClass wclass = kSheetWindowClass;
1970  if(qt_mac_is_macdrawer(q))
1971  wclass = kDrawerWindowClass;
1972  else if (q->testAttribute(Qt::WA_ShowModal) && flags & Qt::CustomizeWindowHint)
1973  wclass = kDocumentWindowClass;
1974  else if(popup || (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && type == Qt::SplashScreen))
1975  wclass = kModalWindowClass;
1976  else if(type == Qt::Dialog)
1977  wclass = kMovableModalWindowClass;
1978  else if(type == Qt::ToolTip)
1979  wclass = kHelpWindowClass;
1981  && type == Qt::SplashScreen))
1982  wclass = kFloatingWindowClass;
1983  else if(q->testAttribute(Qt::WA_ShowModal))
1984  wclass = kMovableModalWindowClass;
1985  else
1986  wclass = kDocumentWindowClass;
1987 
1988  WindowAttributes wattr = NSBorderlessWindowMask;
1989  if(qt_mac_is_macsheet(q)) {
1990  //grp = GetWindowGroupOfClass(kMovableModalWindowClass);
1991  wclass = kSheetWindowClass;
1992  wattr = NSTitledWindowMask | NSResizableWindowMask;
1993  } else {
1994 #ifndef QT_MAC_USE_COCOA
1995  grp = GetWindowGroupOfClass(wclass);
1996 #endif
1997  // Shift things around a bit to get the correct window class based on the presence
1998  // (or lack) of the border.
1999  bool customize = flags & Qt::CustomizeWindowHint;
2000  bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
2001  if (framelessWindow) {
2002  if (wclass == kDocumentWindowClass) {
2003  wclass = kSimpleWindowClass;
2004  } else if (wclass == kFloatingWindowClass) {
2005  wclass = kToolbarWindowClass;
2006  } else if (wclass == kMovableModalWindowClass) {
2007  wclass = kModalWindowClass;
2008  }
2009  } else {
2010  wattr |= NSTitledWindowMask;
2011  if (wclass != kModalWindowClass)
2012  wattr |= NSResizableWindowMask;
2013  }
2014  // Only add extra decorations (well, buttons) for widgets that can have them
2015  // and have an actual border we can put them on.
2016  if (wclass != kModalWindowClass
2017  && wclass != kSheetWindowClass && wclass != kPlainWindowClass
2018  && !framelessWindow && wclass != kDrawerWindowClass
2019  && wclass != kHelpWindowClass) {
2020  if (flags & Qt::WindowMinimizeButtonHint)
2021  wattr |= NSMiniaturizableWindowMask;
2022  if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
2023  wattr |= NSClosableWindowMask;
2024  } else {
2025  // Clear these hints so that we aren't call them on invalid windows
2028  }
2029  }
2030  if (q->testAttribute(Qt::WA_MacBrushedMetal))
2031  wattr |= NSTexturedBackgroundWindowMask;
2032 
2033 #ifdef DEBUG_WINDOW_CREATE
2034 #define ADD_DEBUG_WINDOW_NAME(x) { x, #x }
2035  struct {
2036  UInt32 tag;
2037  const char *name;
2038  } known_attribs[] = {
2039  ADD_DEBUG_WINDOW_NAME(kWindowCompositingAttribute),
2040  ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
2041  ADD_DEBUG_WINDOW_NAME(kWindowMetalAttribute),
2042  ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
2043  ADD_DEBUG_WINDOW_NAME(kWindowStandardHandlerAttribute),
2044  ADD_DEBUG_WINDOW_NAME(kWindowCollapseBoxAttribute),
2045  ADD_DEBUG_WINDOW_NAME(kWindowHorizontalZoomAttribute),
2046  ADD_DEBUG_WINDOW_NAME(kWindowVerticalZoomAttribute),
2047  ADD_DEBUG_WINDOW_NAME(kWindowResizableAttribute),
2048  ADD_DEBUG_WINDOW_NAME(kWindowNoActivatesAttribute),
2049  ADD_DEBUG_WINDOW_NAME(kWindowNoUpdatesAttribute),
2050  ADD_DEBUG_WINDOW_NAME(kWindowOpaqueForEventsAttribute),
2051  ADD_DEBUG_WINDOW_NAME(kWindowLiveResizeAttribute),
2052  ADD_DEBUG_WINDOW_NAME(kWindowCloseBoxAttribute),
2053  ADD_DEBUG_WINDOW_NAME(kWindowHideOnSuspendAttribute),
2054  { 0, 0 }
2055  }, known_classes[] = {
2056  ADD_DEBUG_WINDOW_NAME(kHelpWindowClass),
2057  ADD_DEBUG_WINDOW_NAME(kPlainWindowClass),
2058  ADD_DEBUG_WINDOW_NAME(kDrawerWindowClass),
2059  ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
2060  ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
2061  ADD_DEBUG_WINDOW_NAME(kSheetWindowClass),
2062  ADD_DEBUG_WINDOW_NAME(kFloatingWindowClass),
2063  ADD_DEBUG_WINDOW_NAME(kUtilityWindowClass),
2064  ADD_DEBUG_WINDOW_NAME(kDocumentWindowClass),
2065  ADD_DEBUG_WINDOW_NAME(kToolbarWindowClass),
2066  ADD_DEBUG_WINDOW_NAME(kMovableModalWindowClass),
2067  ADD_DEBUG_WINDOW_NAME(kModalWindowClass),
2068  { 0, 0 }
2069  };
2070  qDebug("Qt: internal: ************* Creating new window %p (%s::%s)", q, q->metaObject()->className(),
2071  q->objectName().toLocal8Bit().constData());
2072  bool found_class = false;
2073  for(int i = 0; known_classes[i].name; i++) {
2074  if(wclass == known_classes[i].tag) {
2075  found_class = true;
2076  qDebug("Qt: internal: ** Class: %s", known_classes[i].name);
2077  break;
2078  }
2079  }
2080  if(!found_class)
2081  qDebug("Qt: internal: !! Class: Unknown! (%d)", (int)wclass);
2082  if(wattr) {
2083  WindowAttributes tmp_wattr = wattr;
2084  qDebug("Qt: internal: ** Attributes:");
2085  for(int i = 0; tmp_wattr && known_attribs[i].name; i++) {
2086  if((tmp_wattr & known_attribs[i].tag) == known_attribs[i].tag) {
2087  tmp_wattr ^= known_attribs[i].tag;
2088  }
2089  }
2090  if(tmp_wattr)
2091  qDebug("Qt: internal: !! Attributes: Unknown (%d)", (int)tmp_wattr);
2092  }
2093 #endif
2094 
2095 #ifndef QT_MAC_USE_COCOA
2096  /* Just to be extra careful we will change to the kUtilityWindowClass if the
2097  requested attributes cannot be used */
2098  if((GetAvailableWindowAttributes(wclass) & wattr) != wattr) {
2099  WindowClass tmp_class = wclass;
2100  if(wclass == kToolbarWindowClass || wclass == kUtilityWindowClass)
2101  wclass = kFloatingWindowClass;
2102  if(tmp_class != wclass) {
2103  if(!grp)
2104  grp = GetWindowGroupOfClass(wclass);
2105  wclass = tmp_class;
2106  }
2107  }
2108 #endif
2109 #endif
2110  topData()->wclass = wclass;
2111  topData()->wattr = wattr;
2112 }
2113 
2114 #ifndef QT_MAC_USE_COCOA // This is handled in Cocoa via our category.
2115 void QWidgetPrivate::initWindowPtr()
2116 {
2117  Q_Q(QWidget);
2118  OSWindowRef windowRef = qt_mac_window_for(qt_mac_nativeview_for(q)); //do not create!
2119  if(!windowRef)
2120  return;
2121  QWidget *window = q->window(), *oldWindow = 0;
2122  if(GetWindowProperty(windowRef, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(oldWindow), 0, &oldWindow) == noErr) {
2123  Q_ASSERT(window == oldWindow);
2124  return;
2125  }
2126 
2127  if(SetWindowProperty(windowRef, kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(window), &window) != noErr)
2128  qWarning("Qt:Internal error (%s:%d)", __FILE__, __LINE__); //no real way to recover
2129  if(!q->windowType() != Qt::Desktop) { //setup an event callback handler on the window
2130  InstallWindowEventHandler(windowRef, make_win_eventUPP(), GetEventTypeCount(window_events),
2131  window_events, static_cast<void *>(qApp), &window_event);
2132  }
2133 }
2134 
2135 void QWidgetPrivate::finishCreateWindow_sys_Carbon(OSWindowRef windowRef)
2136 {
2137  Q_Q(QWidget);
2138  const Qt::WindowType type = q->windowType();
2139  Qt::WindowFlags &flags = data.window_flags;
2141 
2142  const bool desktop = (type == Qt::Desktop);
2143  const bool dialog = (type == Qt::Dialog
2144  || type == Qt::Sheet
2145  || type == Qt::Drawer
2146  || (flags & Qt::MSWindowsFixedSizeDialogHint));
2147  QTLWExtra *topExtra = topData();
2148  quint32 wattr = topExtra->wattr;
2149  if (!desktop)
2150  SetAutomaticControlDragTrackingEnabledForWindow(windowRef, true);
2151  HIWindowChangeFeatures(windowRef, kWindowCanCollapse, 0);
2152  if (wattr & kWindowHideOnSuspendAttribute)
2153  HIWindowChangeAvailability(windowRef, kHIWindowExposeHidden, 0);
2154  else
2155  HIWindowChangeAvailability(windowRef, 0, kHIWindowExposeHidden);
2156  if ((flags & Qt::WindowStaysOnTopHint))
2157  ChangeWindowAttributes(windowRef, kWindowNoAttributes, kWindowHideOnSuspendAttribute);
2158  if (qt_mac_is_macdrawer(q) && parentWidget)
2159  SetDrawerParent(windowRef, qt_mac_window_for (parentWidget));
2160  if (topExtra->group) {
2161  qt_mac_release_window_group(topExtra->group);
2162  topExtra->group = 0;
2163  }
2164  if (type == Qt::ToolTip)
2166  else if (type == Qt::Popup && (flags & Qt::WindowStaysOnTopHint))
2168  else if (flags & Qt::WindowStaysOnTopHint)
2169  qt_mac_set_window_group_to_stays_on_top(windowRef, type);
2170  else if (dialog)
2171  SetWindowGroup(windowRef, GetWindowGroupOfClass(kMovableModalWindowClass));
2172 
2173 #ifdef DEBUG_WINDOW_CREATE
2174  if (WindowGroupRef grpf = GetWindowGroup(windowRef)) {
2175  QCFString cfname;
2176  CopyWindowGroupName(grpf, &cfname);
2177  SInt32 lvl;
2178  GetWindowGroupLevel(grpf, &lvl);
2179  const char *from = "Default";
2180  if (topExtra && grpf == topData()->group)
2181  from = "Created";
2182  else if (grpf == grp)
2183  from = "Copied";
2184  qDebug("Qt: internal: With window group '%s' [%p] @ %d: %s",
2185  static_cast<QString>(cfname).toLatin1().constData(), grpf, (int)lvl, from);
2186  } else {
2187  qDebug("Qt: internal: No window group!!!");
2188  }
2189  HIWindowAvailability hi_avail = 0;
2190  if (HIWindowGetAvailability(windowRef, &hi_avail) == noErr) {
2191  struct {
2192  UInt32 tag;
2193  const char *name;
2194  } known_avail[] = {
2195  ADD_DEBUG_WINDOW_NAME(kHIWindowExposeHidden),
2196  { 0, 0 }
2197  };
2198  qDebug("Qt: internal: ** HIWindowAvailibility:");
2199  for (int i = 0; hi_avail && known_avail[i].name; i++) {
2200  if ((hi_avail & known_avail[i].tag) == known_avail[i].tag) {
2201  hi_avail ^= known_avail[i].tag;
2202  qDebug("Qt: internal: * %s", known_avail[i].name);
2203  }
2204  }
2205  if (hi_avail)
2206  qDebug("Qt: internal: !! Attributes: Unknown (%d)", (int)hi_avail);
2207  }
2208 #undef ADD_DEBUG_WINDOW_NAME
2209 #endif
2210  if (extra && !extra->mask.isEmpty())
2211  ReshapeCustomWindow(windowRef);
2212  SetWindowModality(windowRef, kWindowModalityNone, 0);
2213  if (qt_mac_is_macdrawer(q))
2214  SetDrawerOffsets(windowRef, 0.0, 25.0);
2215  data.fstrut_dirty = true; // when we create a toplevel widget, the frame strut should be dirty
2216  HIViewRef hiview = (HIViewRef)data.winid;
2217  HIViewRef window_hiview = qt_mac_get_contentview_for(windowRef);
2218  if(!hiview) {
2219  hiview = qt_mac_create_widget(q, this, window_hiview);
2220  setWinId((WId)hiview);
2221  } else {
2222  HIViewAddSubview(window_hiview, hiview);
2223  }
2224  if (hiview) {
2225  Rect win_rect;
2226  GetWindowBounds(qt_mac_window_for (window_hiview), kWindowContentRgn, &win_rect);
2227  HIRect bounds = CGRectMake(0, 0, win_rect.right-win_rect.left, win_rect.bottom-win_rect.top);
2228  HIViewSetFrame(hiview, &bounds);
2229  HIViewSetVisible(hiview, true);
2230  if (q->testAttribute(Qt::WA_DropSiteRegistered))
2231  registerDropSite(true);
2232  transferChildren();
2233  }
2234  initWindowPtr();
2235 
2236  if (topExtra->posFromMove) {
2237  updateFrameStrut();
2238  const QRect &fStrut = frameStrut();
2239  Rect r;
2240  SetRect(&r, data.crect.left(), data.crect.top(), data.crect.right() + 1, data.crect.bottom() + 1);
2241  SetRect(&r, r.left + fStrut.left(), r.top + fStrut.top(),
2242  (r.left + fStrut.left() + data.crect.width()) - fStrut.right(),
2243  (r.top + fStrut.top() + data.crect.height()) - fStrut.bottom());
2244  SetWindowBounds(windowRef, kWindowContentRgn, &r);
2245  topExtra->posFromMove = false;
2246  }
2247 
2248  if (q->testAttribute(Qt::WA_WState_WindowOpacitySet)){
2249  q->setWindowOpacity(topExtra->opacity / 255.0f);
2250  } else if (qt_mac_is_macsheet(q)){
2251  SetThemeWindowBackground(qt_mac_window_for(q), kThemeBrushSheetBackgroundTransparent, true);
2252  CGFloat alpha = 0;
2253  GetWindowAlpha(qt_mac_window_for(q), &alpha);
2254  if (alpha == 1){
2255  // For some reason the 'SetThemeWindowBackground' does not seem
2256  // to work. So we do this little hack until it hopefully starts to
2257  // work in newer versions of mac OS.
2258  q->setWindowOpacity(0.95f);
2259  q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
2260  }
2261  } else{
2262  // If the window has been recreated after beeing e.g. a sheet,
2263  // make sure that we don't report a faulty opacity:
2264  q->setWindowOpacity(1.0f);
2265  q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
2266  }
2267 
2268  // Since we only now have a window, sync our state.
2269  macUpdateHideOnSuspend();
2270  macUpdateOpaqueSizeGrip();
2271  macUpdateMetalAttribute();
2272  macUpdateIgnoreMouseEvents();
2276  setWindowModified_sys(q->isWindowModified());
2277  updateFrameStrut();
2278  qt_mac_update_sizer(q);
2279  applyMaxAndMinSizeOnWindow();
2280 }
2281 #else // QT_MAC_USE_COCOA
2282 
2283 void QWidgetPrivate::setWindowLevel()
2284 {
2285  Q_Q(QWidget);
2286  const QWidget * const windowParent = q->window()->parentWidget();
2287  const QWidget * const primaryWindow = windowParent ? windowParent->window() : 0;
2288  NSInteger winLevel = -1;
2289 
2290  if (q->windowType() == Qt::Popup) {
2291  winLevel = NSPopUpMenuWindowLevel;
2292  // Popup should be in at least the same level as its parent.
2293  if (primaryWindow) {
2294  OSWindowRef parentRef = qt_mac_window_for(primaryWindow);
2295  winLevel = qMax([parentRef level], winLevel);
2296  }
2297  } else if (q->windowType() == Qt::Tool) {
2298  winLevel = NSFloatingWindowLevel;
2299  } else if (q->windowType() == Qt::Dialog) {
2300  // Correct modality level (NSModalPanelWindowLevel) will be
2301  // set by cocoa when creating a modal session later.
2302  winLevel = NSNormalWindowLevel;
2303  }
2304 
2305  // StayOnTop window should appear above Tool windows.
2307  winLevel = NSPopUpMenuWindowLevel;
2308  // Tooltips should appear above StayOnTop windows.
2309  if (q->windowType() == Qt::ToolTip)
2310  winLevel = NSScreenSaverWindowLevel;
2311  // All other types are Normal level.
2312  if (winLevel == -1)
2313  winLevel = NSNormalWindowLevel;
2314  [qt_mac_window_for(q) setLevel:winLevel];
2315 }
2316 
2317 void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWindowRef)
2318 {
2319  Q_Q(QWidget);
2321  NSWindow *windowRef = static_cast<NSWindow *>(voidWindowRef);
2322  const Qt::WindowType type = q->windowType();
2323  Qt::WindowFlags &flags = data.window_flags;
2325 
2326  const bool popup = (type == Qt::Popup);
2327  const bool dialog = (type == Qt::Dialog
2328  || type == Qt::Sheet
2329  || type == Qt::Drawer
2330  || (flags & Qt::MSWindowsFixedSizeDialogHint));
2331  QTLWExtra *topExtra = topData();
2332 
2333  if ((popup || type == Qt::Tool || type == Qt::ToolTip) && !q->isModal()) {
2334  [windowRef setHidesOnDeactivate:YES];
2335  } else {
2336  [windowRef setHidesOnDeactivate:NO];
2337  }
2338  if (q->testAttribute(Qt::WA_MacNoShadow))
2339  [windowRef setHasShadow:NO];
2340  else
2341  [windowRef setHasShadow:YES];
2342  Q_UNUSED(parentWidget);
2343  Q_UNUSED(dialog);
2344 
2345  data.fstrut_dirty = true; // when we create a toplevel widget, the frame strut should be dirty
2346 
2347  OSViewRef nsview = (OSViewRef)data.winid;
2348  if (!nsview) {
2349  nsview = qt_mac_create_widget(q, this, 0);
2350  setWinId(WId(nsview));
2351  }
2352  [windowRef setContentView:nsview];
2353  [nsview setHidden:NO];
2354  transferChildren();
2355 
2356  // Tell Cocoa explicit that we wan't the view to receive key events
2357  // (regardless of focus policy) because this is how it works on other
2358  // platforms (and in the carbon port):
2359  [windowRef makeFirstResponder:nsview];
2360 
2361  if (topExtra->posFromMove) {
2362  updateFrameStrut();
2363 
2364  const QRect &fStrut = frameStrut();
2365  const QRect &crect = data.crect;
2366  const QRect frameRect(QPoint(crect.left(), crect.top()),
2367  QSize(fStrut.left() + fStrut.right() + crect.width(),
2368  fStrut.top() + fStrut.bottom() + crect.height()));
2369  NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1),
2370  frameRect.width(), frameRect.height());
2371  [windowRef setFrame:cocoaFrameRect display:NO];
2372  topExtra->posFromMove = false;
2373  }
2374 
2375  if (q->testAttribute(Qt::WA_WState_WindowOpacitySet)){
2376  q->setWindowOpacity(topExtra->opacity / 255.0f);
2377  } else if (qt_mac_is_macsheet(q)){
2378  CGFloat alpha = [qt_mac_window_for(q) alphaValue];
2379  if (alpha >= 1.0) {
2380  q->setWindowOpacity(0.95f);
2381  q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
2382  }
2383  } else{
2384  // If the window has been recreated after beeing e.g. a sheet,
2385  // make sure that we don't report a faulty opacity:
2386  q->setWindowOpacity(1.0f);
2387  q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
2388  }
2389 
2390  // Its more performant to handle the mouse cursor
2391  // ourselves, expecially when using alien widgets:
2392  [windowRef disableCursorRects];
2393 
2394  setWindowLevel();
2395  macUpdateHideOnSuspend();
2396  macUpdateOpaqueSizeGrip();
2397  macUpdateIgnoreMouseEvents();
2400  setWindowModified_sys(q->isWindowModified());
2401  updateFrameStrut();
2402  syncCocoaMask();
2403  macUpdateIsOpaque();
2404  qt_mac_update_sizer(q);
2405  applyMaxAndMinSizeOnWindow();
2406 }
2407 
2408 #endif // QT_MAC_USE_COCOA
2409 
2410 /*
2411  Recreates widget window. Useful if immutable
2412  properties for it has changed.
2413  */
2414 void QWidgetPrivate::recreateMacWindow()
2415 {
2416  Q_Q(QWidget);
2417  OSViewRef myView = qt_mac_nativeview_for(q);
2418  OSWindowRef oldWindow = qt_mac_window_for(myView);
2419 #ifndef QT_MAC_USE_COCOA
2420  HIViewRemoveFromSuperview(myView);
2421  determineWindowClass();
2422  createWindow_sys();
2423 
2424  if (QMainWindowLayout *mwl = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q))) {
2425  mwl->updateHIToolBarStatus();
2426  }
2427 
2428  if (IsWindowVisible(oldWindow))
2429  show_sys();
2430 #else
2432  [myView removeFromSuperview];
2433  determineWindowClass();
2434  createWindow_sys();
2435  if (NSToolbar *toolbar = [oldWindow toolbar]) {
2436  OSWindowRef newWindow = qt_mac_window_for(myView);
2437  [newWindow setToolbar:toolbar];
2438  [toolbar setVisible:[toolbar isVisible]];
2439  }
2440  if ([oldWindow isVisible]){
2441  if ([oldWindow isSheet])
2442  [NSApp endSheet:oldWindow];
2443  [oldWindow orderOut:oldWindow];
2444  show_sys();
2445  }
2446 #endif // QT_MAC_USE_COCOA
2447 
2448  // Release the window after creating the new window, because releasing it early
2449  // may cause the app to quit ("close on last window closed attribute")
2450  qt_mac_destructWindow(oldWindow);
2451 }
2452 
2453 void QWidgetPrivate::createWindow_sys()
2454 {
2455  Q_Q(QWidget);
2456  Qt::WindowFlags &flags = data.window_flags;
2458 
2459  QTLWExtra *topExtra = topData();
2460  if (topExtra->embedded)
2461  return; // Simply return because this view "is" the top window.
2462  quint32 wattr = topExtra->wattr;
2463 
2464  if(parentWidget && (parentWidget->window()->windowFlags() & Qt::WindowStaysOnTopHint)) // If our parent has Qt::WStyle_StaysOnTop, so must we
2465  flags |= Qt::WindowStaysOnTopHint;
2466 
2467  data.fstrut_dirty = true;
2468 
2469  OSWindowRef windowRef = qt_mac_create_window(q, topExtra->wclass, wattr, data.crect);
2470  if (windowRef == 0)
2471  qWarning("QWidget: Internal error: %s:%d: If you reach this error please contact Qt Support and include the\n"
2472  " WidgetFlags used in creating the widget.", __FILE__, __LINE__);
2473 #ifndef QT_MAC_USE_COCOA
2474  finishCreateWindow_sys_Carbon(windowRef);
2475 #else
2476  finishCreateWindow_sys_Cocoa(windowRef);
2477 #endif
2478 }
2479 
2480 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
2481 {
2482  Q_Q(QWidget);
2484 
2485  OSViewRef destroyid = 0;
2486 #ifndef QT_MAC_USE_COCOA
2487  window_event = 0;
2488 #endif
2489 
2490  Qt::WindowType type = q->windowType();
2491  Qt::WindowFlags flags = data.window_flags;
2493 
2494  bool topLevel = (flags & Qt::Window);
2495  bool popup = (type == Qt::Popup);
2496  bool dialog = (type == Qt::Dialog
2497  || type == Qt::Sheet
2498  || type == Qt::Drawer
2499  || (flags & Qt::MSWindowsFixedSizeDialogHint));
2500  bool desktop = (type == Qt::Desktop);
2501 
2502  // Determine this early for top-levels so, we can use it later.
2503  if (topLevel)
2504  determineWindowClass();
2505 
2506  if (desktop) {
2507  QSize desktopSize = qt_mac_desktopSize();
2508  q->setAttribute(Qt::WA_WState_Visible);
2509  data.crect.setRect(0, 0, desktopSize.width(), desktopSize.height());
2510  dialog = popup = false; // force these flags off
2511  } else {
2512  if (topLevel && (type != Qt::Drawer)) {
2513  if (QDesktopWidget *dsk = QApplication::desktop()) { // calc pos/size from screen
2514  const bool wasResized = q->testAttribute(Qt::WA_Resized);
2515  const bool wasMoved = q->testAttribute(Qt::WA_Moved);
2516  int deskn = dsk->primaryScreen();
2517  if (parentWidget && parentWidget->windowType() != Qt::Desktop)
2518  deskn = dsk->screenNumber(parentWidget);
2519  QRect screenGeo = dsk->screenGeometry(deskn);
2520  if (!wasResized) {
2521 #ifndef QT_MAC_USE_COCOA
2522  data.crect.setSize(QSize(screenGeo.width()/2, 4*screenGeo.height()/10));
2523 #else
2524  NSRect newRect = [NSWindow frameRectForContentRect:NSMakeRect(0, 0,
2525  screenGeo.width() / 2.,
2526  4 * screenGeo.height() / 10.)
2527  styleMask:topData()->wattr];
2528  data.crect.setSize(QSize(newRect.size.width, newRect.size.height));
2529 #endif
2530  // Constrain to minimums and maximums we've set
2531  if (extra->minw > 0)
2533  if (extra->minh > 0)
2535  if (extra->maxw > 0)
2537  if (extra->maxh > 0)
2539  }
2540  if (!wasMoved && !q->testAttribute(Qt::WA_DontShowOnScreen))
2541  data.crect.moveTopLeft(QPoint(screenGeo.width()/4,
2542  3 * screenGeo.height() / 10));
2543  }
2544  }
2545  }
2546 
2547 
2548  if(!window) // always initialize
2549  initializeWindow=true;
2550 
2551  hd = 0;
2552  if(window) { // override the old window (with a new NSView)
2553  OSViewRef nativeView = OSViewRef(window);
2554  OSViewRef parent = 0;
2555 #ifndef QT_MAC_USE_COCOA
2556  CFRetain(nativeView);
2557 #else
2558  [nativeView retain];
2559 #endif
2560  if (destroyOldWindow)
2561  destroyid = qt_mac_nativeview_for(q);
2562  bool transfer = false;
2563  setWinId((WId)nativeView);
2564 #ifndef QT_MAC_USE_COCOA
2565 #ifndef HIViewInstallEventHandler
2566  // Macro taken from the CarbonEvents Header on Tiger
2567 #define HIViewInstallEventHandler( target, handler, numTypes, list, userData, outHandlerRef ) \
2568  InstallEventHandler( HIObjectGetEventTarget( (HIObjectRef) (target) ), (handler), (numTypes), (list), (userData), (outHandlerRef) )
2569 #endif
2570  HIViewInstallEventHandler(nativeView, make_widget_eventUPP(), GetEventTypeCount(widget_events), widget_events, 0, 0);
2571 #endif
2572  if(topLevel) {
2573  for(int i = 0; i < 2; ++i) {
2574  if(i == 1) {
2575  if(!initializeWindow)
2576  break;
2577  createWindow_sys();
2578  }
2579  if(OSWindowRef windowref = qt_mac_window_for(nativeView)) {
2580 #ifndef QT_MAC_USE_COCOA
2581  CFRetain(windowref);
2582 #else
2583  [windowref retain];
2584 #endif
2585  if (initializeWindow) {
2586  parent = qt_mac_get_contentview_for(windowref);
2587  } else {
2588 #ifndef QT_MAC_USE_COCOA
2589  parent = HIViewGetSuperview(nativeView);
2590 #else
2591  parent = [nativeView superview];
2592 #endif
2593  }
2594  break;
2595  }
2596  }
2597  if(!parent)
2598  transfer = true;
2599  } else if (parentWidget) {
2600  // I need to be added to my parent, therefore my parent needs an NSView
2601  // Alien note: a 'window' was supplied as argument, meaning this widget
2602  // is not alien. So therefore the parent cannot be alien either.
2603  parentWidget->createWinId();
2604  parent = qt_mac_nativeview_for(parentWidget);
2605  }
2606  if(parent != nativeView && parent) {
2607 #ifndef QT_MAC_USE_COCOA
2608  HIViewAddSubview(parent, nativeView);
2609 #else
2610  [parent addSubview:nativeView];
2611 #endif
2612  }
2613  if(transfer)
2614  transferChildren();
2615  data.fstrut_dirty = true; // we'll re calculate this later
2616  q->setAttribute(Qt::WA_WState_Visible,
2617 #ifndef QT_MAC_USE_COCOA
2618  HIViewIsVisible(nativeView)
2619 #else
2620  ![nativeView isHidden]
2621 #endif
2622  );
2623  if(initializeWindow) {
2624 #ifndef QT_MAC_USE_COCOA
2625  HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
2626  HIViewSetFrame(nativeView, &bounds);
2627  q->setAttribute(Qt::WA_WState_Visible, HIViewIsVisible(nativeView));
2628 #else
2629  NSRect bounds = NSMakeRect(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
2630  [nativeView setFrame:bounds];
2631  q->setAttribute(Qt::WA_WState_Visible, [nativeView isHidden]);
2632 #endif
2633  }
2634 #ifndef QT_MAC_USE_COCOA
2635  initWindowPtr();
2636 #endif
2637  } else if (desktop) { // desktop widget
2638  if (!qt_root_win)
2639  QWidgetPrivate::qt_create_root_win();
2641  WId rootWinID = 0;
2642 #ifndef QT_MAC_USE_COCOA
2643  CFRetain(qt_root_win);
2644  if(HIViewRef rootContentView = HIViewGetRoot(qt_root_win)) {
2645  rootWinID = (WId)rootContentView;
2646  CFRetain(rootContentView);
2647  }
2648 #else
2649  [qt_root_win retain];
2650  if (OSViewRef rootContentView = [qt_root_win contentView]) {
2651  rootWinID = (WId)rootContentView;
2652  [rootContentView retain];
2653  }
2654 #endif
2655  setWinId(rootWinID);
2656  } else if (topLevel) {
2657  determineWindowClass();
2658  if(OSViewRef osview = qt_mac_create_widget(q, this, 0)) {
2659 #ifndef QT_MAC_USE_COCOA
2660  HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(),
2661  data.crect.width(), data.crect.height());
2662  HIViewSetFrame(osview, &bounds);
2663 #else
2664  NSRect bounds = NSMakeRect(data.crect.x(), flipYCoordinate(data.crect.y()),
2665  data.crect.width(), data.crect.height());
2666  [osview setFrame:bounds];
2667 #endif
2668  setWinId((WId)osview);
2669  }
2670  } else {
2671  data.fstrut_dirty = false; // non-toplevel widgets don't have a frame, so no need to update the strut
2672 
2673 #ifdef QT_MAC_USE_COCOA
2674  if (q->testAttribute(Qt::WA_NativeWindow) == false || q->internalWinId() != 0) {
2675  // INVARIANT: q is Alien, and we should not create an NSView to back it up.
2676  } else
2677 #endif
2678  if (OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) {
2679 #ifndef QT_MAC_USE_COCOA
2680  HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
2681  HIViewSetFrame(osview, &bounds);
2682  setWinId((WId)osview);
2683 #else
2684  NSRect bounds = NSMakeRect(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
2685  [osview setFrame:bounds];
2686  setWinId((WId)osview);
2687  if (q->isVisible()) {
2688  // If q were Alien before, but now became native (e.g. if a call to
2689  // winId was done from somewhere), we need to show the view immidiatly:
2691  [osview setHidden:NO];
2692  }
2693 #endif
2694  }
2695  }
2696 
2697  updateIsOpaque();
2698 
2699  if (q->testAttribute(Qt::WA_DropSiteRegistered))
2700  registerDropSite(true);
2701  if (q->hasFocus())
2702  setFocus_sys();
2703  if (!topLevel && initializeWindow)
2704  setWSGeometry();
2705  if (destroyid)
2706  qt_mac_destructView(destroyid);
2707 }
2708 
2717 Qt::HANDLE
2719 {
2720 #ifndef QT_MAC_USE_COCOA
2721  return d_func()->qd_hd;
2722 #else
2723  return 0;
2724 #endif
2725 }
2726 
2734 Qt::HANDLE
2736 {
2737  return handle();
2738 }
2739 
2741 {
2742  QWidget *nativeParent = alienWidget->nativeParentWidget();
2743  if (!nativeParent)
2744  return;
2745 
2746  QPoint globalPos = alienWidget->mapToGlobal(QPoint(0, 0));
2747  QRect dirtyRect = QRect(nativeParent->mapFromGlobal(globalPos), alienWidget->size());
2748  nativeParent->update(dirtyRect);
2749 }
2750 
2751 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
2752 {
2753  Q_D(QWidget);
2755  d->aboutToDestroy();
2756  if (!isWindow() && parentWidget())
2757  parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
2758  if (!internalWinId())
2760  d->deactivateWidgetCleanup();
2761  qt_mac_event_release(this);
2762  if(testAttribute(Qt::WA_WState_Created)) {
2763  setAttribute(Qt::WA_WState_Created, false);
2764  QObjectList chldrn = children();
2765  for(int i = 0; i < chldrn.size(); i++) { // destroy all widget children
2766  QObject *obj = chldrn.at(i);
2767  if(obj->isWidgetType())
2768  static_cast<QWidget*>(obj)->destroy(destroySubWindows, destroySubWindows);
2769  }
2770  if(mac_mouse_grabber == this)
2771  releaseMouse();
2772  if(mac_keyboard_grabber == this)
2773  releaseKeyboard();
2774 
2775  if(testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal
2777  else if((windowType() == Qt::Popup))
2778  qApp->d_func()->closePopup(this);
2779  if (destroyWindow) {
2780  if(OSViewRef hiview = qt_mac_nativeview_for(this)) {
2781  OSWindowRef window = 0;
2782  NSDrawer *drawer = nil;
2783 #ifdef QT_MAC_USE_COCOA
2784  if (qt_mac_is_macdrawer(this)) {
2785  drawer = qt_mac_drawer_for(this);
2786  } else
2787 #endif
2788  if (isWindow())
2789  window = qt_mac_window_for(hiview);
2790 
2791  // Because of how "destruct" works, we have to do just a normal release for the root_win.
2792  if (window && window == qt_root_win) {
2793 #ifndef QT_MAC_USE_COCOA
2794  CFRelease(hiview);
2795 #else
2796  [hiview release];
2797 #endif
2798  } else {
2799  qt_mac_destructView(hiview);
2800  }
2801  if (drawer)
2802  qt_mac_destructDrawer(drawer);
2803  if (window)
2804  qt_mac_destructWindow(window);
2805  }
2806 #ifdef QT_MAC_USE_COCOA
2807  if (isWindow())
2809 #endif
2810  }
2811  QT_TRY {
2812  d->setWinId(0);
2813  } QT_CATCH (const std::bad_alloc &) {
2814  // swallow - destructors must not throw
2815  }
2816  }
2817 }
2818 
2819 void QWidgetPrivate::transferChildren()
2820 {
2821  Q_Q(QWidget);
2822  if (!q->internalWinId())
2823  return; // Can't add any views anyway
2824 
2825  QObjectList chlist = q->children();
2826  for (int i = 0; i < chlist.size(); ++i) {
2827  QObject *obj = chlist.at(i);
2828  if (obj->isWidgetType()) {
2829  QWidget *w = (QWidget *)obj;
2830  if (!w->isWindow()) {
2831  // This seems weird, no need to call it in a loop right?
2832  if (!topData()->caption.isEmpty())
2834  if (w->internalWinId()) {
2835 #ifndef QT_MAC_USE_COCOA
2836  HIViewAddSubview(qt_mac_nativeview_for(q), qt_mac_nativeview_for(w));
2837 #else
2838  // New NSWindows get an extra reference when drops are
2839  // registered (at least in 10.5) which means that we may
2840  // access the window later and get a crash (becasue our
2841  // widget is dead). Work around this be having the drop
2842  // site disabled until it is part of the new hierarchy.
2843  bool oldRegistered = w->testAttribute(Qt::WA_DropSiteRegistered);
2845  [qt_mac_nativeview_for(w) retain];
2846  [qt_mac_nativeview_for(w) removeFromSuperview];
2847  [qt_mac_nativeview_for(q) addSubview:qt_mac_nativeview_for(w)];
2848  [qt_mac_nativeview_for(w) release];
2849  w->setAttribute(Qt::WA_DropSiteRegistered, oldRegistered);
2850 #endif
2851  }
2852  }
2853  }
2854  }
2855 }
2856 
2857 #ifdef QT_MAC_USE_COCOA
2858 void QWidgetPrivate::setSubWindowStacking(bool set)
2859 {
2860  // After hitting too many unforeseen bugs trying to put Qt on top of the cocoa child
2861  // window API, we have decided to revert this behaviour as much as we can. We
2862  // therefore now only allow child windows to exist for children of modal dialogs.
2863  static bool use_behaviour_qt473 = !qgetenv("QT_MAC_USE_CHILDWINDOWS").isEmpty();
2864 
2865  // This will set/remove a visual relationship between parent and child on screen.
2866  // The reason for doing this is to ensure that a child always stacks infront of
2867  // its parent. Unfortunatly is turns out that [NSWindow addChildWindow] has
2868  // several unwanted side-effects, one of them being the moving of a child when
2869  // moving the parent, which we choose to accept. A way tougher side-effect is
2870  // that Cocoa will hide the parent if you hide the child. And in the case of
2871  // a tool window, since it will normally hide when you deactivate the
2872  // application, Cocoa will hide the parent upon deactivate as well. The result often
2873  // being no more visible windows on screen. So, to make a long story short, we only
2874  // allow parent-child relationships between windows that both are either a plain window
2875  // or a dialog.
2876 
2877  Q_Q(QWidget);
2878  if (!q->isWindow())
2879  return;
2880  NSWindow *qwin = [qt_mac_nativeview_for(q) window];
2881  if (!qwin)
2882  return;
2883  Qt::WindowType qtype = q->windowType();
2884  if (set && !(qtype == Qt::Window || qtype == Qt::Dialog))
2885  return;
2886  if (set && ![qwin isVisible])
2887  return;
2888 
2889  if (QWidget *parent = q->parentWidget()) {
2890  if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) {
2891  if (set) {
2892  Qt::WindowType ptype = parent->window()->windowType();
2893  if ([pwin isVisible]
2894  && (ptype == Qt::Window || ptype == Qt::Dialog)
2895  && ![qwin parentWindow]
2896  && (use_behaviour_qt473 || parent->windowModality() == Qt::ApplicationModal)) {
2897  NSInteger level = [qwin level];
2898  [pwin addChildWindow:qwin ordered:NSWindowAbove];
2899  if ([qwin level] < level)
2900  [qwin setLevel:level];
2901  }
2902  } else {
2903  [pwin removeChildWindow:qwin];
2904  }
2905  }
2906  }
2907 
2908  // Only set-up child windows for q if q is modal:
2909  if (set && !use_behaviour_qt473 && q->windowModality() != Qt::ApplicationModal)
2910  return;
2911 
2912  QObjectList widgets = q->children();
2913  for (int i=0; i<widgets.size(); ++i) {
2914  QWidget *child = qobject_cast<QWidget *>(widgets.at(i));
2915  if (child && child->isWindow()) {
2916  if (NSWindow *cwin = [qt_mac_nativeview_for(child) window]) {
2917  if (set) {
2918  Qt::WindowType ctype = child->window()->windowType();
2919  if ([cwin isVisible] && (ctype == Qt::Window || ctype == Qt::Dialog) && ![cwin parentWindow]) {
2920  NSInteger level = [cwin level];
2921  [qwin addChildWindow:cwin ordered:NSWindowAbove];
2922  if ([cwin level] < level)
2923  [cwin setLevel:level];
2924  }
2925  } else {
2926  [qwin removeChildWindow:qt_mac_window_for(child)];
2927  }
2928  }
2929  }
2930  }
2931 }
2932 #endif
2933 
2935 {
2936  Q_Q(QWidget);
2939  bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
2940 #ifdef QT_MAC_USE_COCOA
2941  bool wasWindow = q->isWindow();
2942 #endif
2943  OSViewRef old_id = 0;
2944 
2945  if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
2946  q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
2947 
2948  // Maintain the glWidgets list on parent change: remove "our" gl widgets
2949  // from the list on the old parent and grandparents.
2950  if (glWidgets.isEmpty() == false) {
2951  QWidget *current = q->parentWidget();
2952  while (current) {
2953  for (QList<QWidgetPrivate::GlWidgetInfo>::const_iterator it = glWidgets.constBegin();
2954  it != glWidgets.constEnd(); ++it)
2955  current->d_func()->glWidgets.removeAll(*it);
2956 
2957  if (current->isWindow())
2958  break;
2959  current = current->parentWidget();
2960  }
2961  }
2962 
2963 #ifndef QT_MAC_USE_COCOA
2964  EventHandlerRef old_window_event = 0;
2965 #else
2966  bool oldToolbarVisible = false;
2967  NSDrawer *oldDrawer = nil;
2968  NSToolbar *oldToolbar = 0;
2969 #endif
2970  if (wasCreated && !(q->windowType() == Qt::Desktop)) {
2971  old_id = qt_mac_nativeview_for(q);
2972 #ifndef QT_MAC_USE_COCOA
2973  old_window_event = window_event;
2974 #else
2975  if (qt_mac_is_macdrawer(q)) {
2976  oldDrawer = qt_mac_drawer_for(q);
2977  }
2978  if (wasWindow) {
2979  OSWindowRef oldWindow = qt_mac_window_for(old_id);
2980  oldToolbar = [oldWindow toolbar];
2981  if (oldToolbar) {
2982  [oldToolbar retain];
2983  oldToolbarVisible = [oldToolbar isVisible];
2984  [oldWindow setToolbar:nil];
2985  }
2986  }
2987 #endif
2988  }
2989  QWidget* oldtlw = q->window();
2990 
2991  if (q->testAttribute(Qt::WA_DropSiteRegistered))
2993 
2994  //recreate and setup flags
2996  bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
2997  if (wasCreated && !qt_isGenuineQWidget(q))
2998  return;
2999 
3000  if (!q->testAttribute(Qt::WA_WState_WindowOpacitySet)) {
3001  q->setWindowOpacity(1.0f);
3002  q->setAttribute(Qt::WA_WState_WindowOpacitySet, false);
3003  }
3004 
3005  setWinId(0); //do after the above because they may want the id
3006 
3007  data.window_flags = f;
3008  q->setAttribute(Qt::WA_WState_Created, false);
3009  q->setAttribute(Qt::WA_WState_Visible, false);
3010  q->setAttribute(Qt::WA_WState_Hidden, false);
3012  // keep compatibility with previous versions, we need to preserve the created state.
3013  // (but we recreate the winId for the widget being reparented, again for compatibility,
3014  // unless this is an alien widget. )
3015  const bool nonWindowWithCreatedParent = !q->isWindow() && parent->testAttribute(Qt::WA_WState_Created);
3016  const bool nativeWidget = q->internalWinId() != 0;
3017  if (wasCreated || (nativeWidget && nonWindowWithCreatedParent)) {
3018  createWinId();
3019  if (q->isWindow()) {
3020 #ifndef QT_MAC_USE_COCOA
3021  // We do this down below for wasCreated, so avoid doing this twice
3022  // (only for performance, it gets called a lot anyway).
3023  if (!wasCreated) {
3024  if (QMainWindowLayout *mwl = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q))) {
3025  mwl->updateHIToolBarStatus();
3026  }
3027  }
3028 #else
3029  // Simply transfer our toolbar over. Everything should stay put, unlike in Carbon.
3030  if (oldToolbar && !(f & Qt::FramelessWindowHint)) {
3031  OSWindowRef newWindow = qt_mac_window_for(q);
3032  [newWindow setToolbar:oldToolbar];
3033  [oldToolbar release];
3034  [oldToolbar setVisible:oldToolbarVisible];
3035  }
3036 #endif
3037  }
3038  }
3039  if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
3040  q->setAttribute(Qt::WA_WState_Hidden);
3041  q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
3042 
3043 #ifdef QT_MAC_USE_COCOA
3044  // If we add a child to the unified toolbar, we have to redirect the painting.
3045  if (parent && parent->d_func() && parent->d_func()->isInUnifiedToolbar) {
3046  if (parent->d_func()->unifiedSurface) {
3047  QWidget *toolbar = parent->d_func()->toolbar_ancestor;
3048  parent->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset);
3049  }
3050  }
3051 #endif // QT_MAC_USE_COCOA
3052 
3053  if (wasCreated) {
3054  transferChildren();
3055 #ifndef QT_MAC_USE_COCOA
3056  // If we were a unified window, We just transfered our toolbars out of the unified toolbar.
3057  // So redo the status one more time. It apparently is not an issue with Cocoa.
3058  if (q->isWindow()) {
3059  if (QMainWindowLayout *mwl = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q))) {
3060  mwl->updateHIToolBarStatus();
3061  }
3062  }
3063 #endif
3064 
3065  if (topData &&
3066  (!topData->caption.isEmpty() || !topData->filePath.isEmpty()))
3067  setWindowTitle_helper(q->windowTitle());
3068  }
3069 
3070  if (q->testAttribute(Qt::WA_AcceptDrops)
3071  || (!q->isWindow() && q->parentWidget()
3072  && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
3073  q->setAttribute(Qt::WA_DropSiteRegistered, true);
3074 
3075  //cleanup
3076 #ifndef QT_MAC_USE_COCOA
3077  if (old_window_event)
3078  RemoveEventHandler(old_window_event);
3079 #endif
3080  if (old_id) { //don't need old window anymore
3081  OSWindowRef window = (oldtlw == q) ? qt_mac_window_for(old_id) : 0;
3082  qt_mac_destructView(old_id);
3083 
3084 #ifdef QT_MAC_USE_COCOA
3085  if (oldDrawer) {
3086  qt_mac_destructDrawer(oldDrawer);
3087  } else
3088 #endif
3089  if (window)
3090  qt_mac_destructWindow(window);
3091  }
3092 
3093  // Maintain the glWidgets list on parent change: add "our" gl widgets
3094  // to the list on the new parent and grandparents.
3095  if (glWidgets.isEmpty() == false) {
3096  QWidget *current = q->parentWidget();
3097  while (current) {
3098  current->d_func()->glWidgets += glWidgets;
3099  if (current->isWindow())
3100  break;
3101  current = current->parentWidget();
3102  }
3103  }
3104  invalidateBuffer(q->rect());
3106 }
3107 
3109 {
3110  Q_D(const QWidget);
3111  if (!internalWinId()) {
3112  QPoint p = pos + data->crect.topLeft();
3113  return isWindow() ? p : parentWidget()->mapToGlobal(p);
3114  }
3115 #ifndef QT_MAC_USE_COCOA
3116  QPoint tmp = d->mapToWS(pos);
3117  HIPoint hi_pos = CGPointMake(tmp.x(), tmp.y());
3118  HIViewConvertPoint(&hi_pos, qt_mac_nativeview_for(this), 0);
3119  Rect win_rect;
3120  GetWindowBounds(qt_mac_window_for(this), kWindowStructureRgn, &win_rect);
3121  return QPoint((int)hi_pos.x+win_rect.left, (int)hi_pos.y+win_rect.top);
3122 #else
3123  QPoint tmp = d->mapToWS(pos);
3124  NSPoint hi_pos = NSMakePoint(tmp.x(), tmp.y());
3125  hi_pos = [qt_mac_nativeview_for(this) convertPoint:hi_pos toView:nil];
3126  NSRect win_rect = [qt_mac_window_for(this) frame];
3127  hi_pos.x += win_rect.origin.x;
3128  hi_pos.y += win_rect.origin.y;
3129  // If we aren't the desktop we need to flip, if you flip the desktop on itself, you get the other problem.
3130  return ((window()->windowFlags() & Qt::Desktop) == Qt::Desktop) ? QPointF(hi_pos.x, hi_pos.y).toPoint()
3131  : flipPoint(hi_pos).toPoint();
3132 #endif
3133 }
3134 
3136 {
3137  Q_D(const QWidget);
3138  if (!internalWinId()) {
3139  QPoint p = isWindow() ? pos : parentWidget()->mapFromGlobal(pos);
3140  return p - data->crect.topLeft();
3141  }
3142 #ifndef QT_MAC_USE_COCOA
3143  Rect win_rect;
3144  GetWindowBounds(qt_mac_window_for(this), kWindowStructureRgn, &win_rect);
3145  HIPoint hi_pos = CGPointMake(pos.x()-win_rect.left, pos.y()-win_rect.top);
3146  HIViewConvertPoint(&hi_pos, 0, qt_mac_nativeview_for(this));
3147  return d->mapFromWS(QPoint((int)hi_pos.x, (int)hi_pos.y));
3148 #else
3149  NSRect win_rect = [qt_mac_window_for(this) frame];
3150  // The Window point is in "Cocoa coordinates," but the view is in "Qt coordinates"
3151  // so make sure to keep them in sync.
3152  NSPoint hi_pos = NSMakePoint(pos.x()-win_rect.origin.x,
3153  flipYCoordinate(pos.y())-win_rect.origin.y);
3154  hi_pos = [qt_mac_nativeview_for(this) convertPoint:hi_pos fromView:0];
3155  return d->mapFromWS(QPoint(qRound(hi_pos.x), qRound(hi_pos.y)));
3156 #endif
3157 }
3158 
3160 {
3161 }
3162 
3164 {
3166 }
3167 
3169 {
3171 }
3172 
3174 {
3175  Q_Q(QWidget);
3176  if (q->isWindow()) {
3177 #ifndef QT_MAC_USE_COCOA
3178  SetWindowTitleWithCFString(qt_mac_window_for(q), QCFString(caption));
3179 #else
3181  [qt_mac_window_for(q) setTitle:qt_mac_QStringToNSString(caption)];
3182 #endif
3183  }
3184 }
3185 
3186 void QWidgetPrivate::setWindowModified_sys(bool mod)
3187 {
3188  Q_Q(QWidget);
3189  if (q->isWindow() && q->testAttribute(Qt::WA_WState_Created)) {
3190 #ifndef QT_MAC_USE_COCOA
3191  SetWindowModified(qt_mac_window_for(q), mod);
3192 #else
3193  [qt_mac_window_for(q) setDocumentEdited:mod];
3194 #endif
3195  }
3196 }
3197 
3198 void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath)
3199 {
3200  Q_Q(QWidget);
3201 #ifdef QT_MAC_USE_COCOA
3203  QFileInfo fi(filePath);
3204  [qt_mac_window_for(q) setRepresentedFilename:fi.exists() ? qt_mac_QStringToNSString(filePath) : @""];
3205 #else
3206  bool validRef = false;
3207  FSRef ref;
3208  bzero(&ref, sizeof(ref));
3209  OSStatus status;
3210 
3211  if (!filePath.isEmpty()) {
3212  status = FSPathMakeRef(reinterpret_cast<const UInt8 *>(filePath.toUtf8().constData()), &ref, 0);
3213  validRef = (status == noErr);
3214  }
3215  // Set the proxy regardless, since this is our way of clearing it as well, but ignore the
3216  // return value as well.
3217  if (validRef) {
3218  status = HIWindowSetProxyFSRef(qt_mac_window_for(q), &ref);
3219  } else {
3220  status = RemoveWindowProxy(qt_mac_window_for(q));
3221  }
3222  if (status != noErr)
3223  qWarning("QWidget::setWindowFilePath: Error setting proxyicon for path (%s):%ld",
3224  qPrintable(filePath), status);
3225 #endif
3226 }
3227 
3229 {
3230  Q_Q(QWidget);
3231 
3232  if (!q->testAttribute(Qt::WA_WState_Created))
3233  return;
3234 
3235  QTLWExtra *topData = this->topData();
3236  if (topData->iconPixmap && !forceReset) // already set
3237  return;
3238 
3239  QIcon icon = q->windowIcon();
3240  QPixmap *pm = 0;
3241  if (!icon.isNull()) {
3242  // now create the extra
3243  if (!topData->iconPixmap) {
3244  pm = new QPixmap(icon.pixmap(QSize(22, 22)));
3245  topData->iconPixmap = pm;
3246  } else {
3247  pm = topData->iconPixmap;
3248  }
3249  }
3250  if (q->isWindow()) {
3251 #ifndef QT_MAC_USE_COCOA
3252  IconRef previousIcon = 0;
3253  if (icon.isNull()) {
3254  RemoveWindowProxy(qt_mac_window_for(q));
3255  previousIcon = topData->windowIcon;
3256  topData->windowIcon = 0;
3257  } else {
3258  WindowClass wclass;
3259  GetWindowClass(qt_mac_window_for(q), &wclass);
3260 
3261  if (wclass == kDocumentWindowClass) {
3262  IconRef newIcon = qt_mac_create_iconref(*pm);
3263  previousIcon = topData->windowIcon;
3264  topData->windowIcon = newIcon;
3265  SetWindowProxyIcon(qt_mac_window_for(q), newIcon);
3266  }
3267  }
3268 
3269  // Release the previous icon if it was set by this function.
3270  if (previousIcon != 0)
3271  ReleaseIconRef(previousIcon);
3272 #else
3274  if (icon.isNull())
3275  return;
3276  NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
3277  if (iconButton == nil) {
3278  QCFString string(q->windowTitle());
3279  const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
3280  [qt_mac_window_for(q) setRepresentedURL:[NSURL fileURLWithPath:const_cast<NSString *>(tmpString)]];
3281  iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
3282  }
3283  if (icon.isNull()) {
3284  [iconButton setImage:nil];
3285  } else {
3287  NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(scaled));
3288  [iconButton setImage:image];
3289  [image release];
3290  }
3291 #endif
3292  }
3293 }
3294 
3296 {
3297  Q_Q(QWidget);
3298  if(q->isWindow() && !iconText.isEmpty()) {
3299 #ifndef QT_MAC_USE_COCOA
3300  SetWindowAlternateTitle(qt_mac_window_for(q), QCFString(iconText));
3301 #else
3303  [qt_mac_window_for(q) setMiniwindowTitle:qt_mac_QStringToNSString(iconText)];
3304 #endif
3305  }
3306 }
3307 
3309 {
3310  if(isVisible() && !qt_nograb()) {
3311  if(mac_mouse_grabber)
3312  mac_mouse_grabber->releaseMouse();
3313  mac_mouse_grabber=this;
3315  }
3316 }
3317 
3318 #ifndef QT_NO_CURSOR
3319 void QWidget::grabMouse(const QCursor &cursor)
3320 {
3321  if(isVisible() && !qt_nograb()) {
3322  if(mac_mouse_grabber)
3323  mac_mouse_grabber->releaseMouse();
3324  mac_mouse_grabber=this;
3325  qt_mac_setMouseGrabCursor(true, const_cast<QCursor *>(&cursor));
3326  }
3327 }
3328 #endif
3329 
3331 {
3332  if(!qt_nograb() && mac_mouse_grabber == this) {
3333  mac_mouse_grabber = 0;
3335  }
3336 }
3337 
3339 {
3340  if(!qt_nograb()) {
3341  if(mac_keyboard_grabber)
3342  mac_keyboard_grabber->releaseKeyboard();
3343  mac_keyboard_grabber = this;
3344  }
3345 }
3346 
3348 {
3349  if(!qt_nograb() && mac_keyboard_grabber == this)
3350  mac_keyboard_grabber = 0;
3351 }
3352 
3354 {
3355  return mac_mouse_grabber;
3356 }
3357 
3359 {
3360  return mac_keyboard_grabber;
3361 }
3362 
3364 {
3365  QWidget *tlw = window();
3366  if(!tlw->isVisible() || !tlw->isWindow() || (tlw->windowType() == Qt::Desktop))
3367  return;
3369 
3370  QWidget *fullScreenWidget = tlw;
3371  QWidget *parentW = tlw;
3372  // Find the oldest parent or the parent with fullscreen, whichever comes first.
3373  while (parentW) {
3374  fullScreenWidget = parentW->window();
3375  if (fullScreenWidget->windowState() & Qt::WindowFullScreen)
3376  break;
3377  parentW = fullScreenWidget->parentWidget();
3378  }
3379 
3380  if (fullScreenWidget->windowType() != Qt::ToolTip) {
3382  qApp->desktop()->screenNumber(this) == 0);
3383  }
3384 
3385  bool windowActive;
3386  OSWindowRef win = qt_mac_window_for(tlw);
3387 #ifndef QT_MAC_USE_COCOA
3388  windowActive = IsWindowActive(win);
3389 #else
3391  windowActive = [win isKeyWindow];
3392 #endif
3393  if ((tlw->windowType() == Qt::Popup)
3394  || (tlw->windowType() == Qt::Tool)
3395  || qt_mac_is_macdrawer(tlw)
3396  || windowActive) {
3397 #ifndef QT_MAC_USE_COCOA
3398  ActivateWindow(win, true);
3399  qApp->setActiveWindow(tlw);
3400 #else
3401  [win makeKeyWindow];
3402 #endif
3403  } else if(!isMinimized()) {
3404 #ifndef QT_MAC_USE_COCOA
3405  SelectWindow(win);
3406 #else
3407  [win makeKeyAndOrderFront:win];
3408 #endif
3409  }
3410 }
3411 
3413 {
3414  return new QMacWindowSurface(q_func());
3415 }
3416 
3417 void QWidgetPrivate::update_sys(const QRect &r)
3418 {
3419  Q_Q(QWidget);
3421  return;
3422  dirtyOnWidget += r;
3423  macSetNeedsDisplay(r != q->rect() ? r : QRegion());
3424 }
3425 
3426 void QWidgetPrivate::update_sys(const QRegion &rgn)
3427 {
3428  Q_Q(QWidget);
3430  return;
3431  dirtyOnWidget += rgn;
3432  macSetNeedsDisplay(rgn);
3433 }
3434 
3435 bool QWidgetPrivate::isRealWindow() const
3436 {
3437  return q_func()->isWindow() && !topData()->embedded;
3438 }
3439 
3441 {
3442  Q_Q(QWidget);
3443  if ((q->windowType() == Qt::Desktop)) //desktop is always visible
3444  return;
3445 
3446  invalidateBuffer(q->rect());
3447  if (q->testAttribute(Qt::WA_OutsideWSRange))
3448  return;
3450  q->setAttribute(Qt::WA_Mapped);
3451  if (q->testAttribute(Qt::WA_DontShowOnScreen))
3452  return;
3453 
3454  bool realWindow = isRealWindow();
3455 #ifndef QT_MAC_USE_COCOA
3456  if (realWindow && !q->testAttribute(Qt::WA_Moved)) {
3457  if (qt_mac_is_macsheet(q))
3458  recreateMacWindow();
3459  q->createWinId();
3460  if (QWidget *p = q->parentWidget()) {
3461  p->createWinId();
3462  RepositionWindow(qt_mac_window_for(q), qt_mac_window_for(p), kWindowCenterOnParentWindow);
3463  } else {
3464  RepositionWindow(qt_mac_window_for(q), 0, kWindowCenterOnMainScreen);
3465  }
3466  }
3467 #endif
3468 
3469  data.fstrut_dirty = true;
3470  if (realWindow) {
3471  bool isCurrentlyMinimized = (q->windowState() & Qt::WindowMinimized);
3472  setModal_sys();
3474 #ifndef QT_MAC_USE_COCOA
3475  SizeWindow(window, q->width(), q->height(), true);
3476 #endif
3477 
3478 #ifdef QT_MAC_USE_COCOA
3479  // Make sure that we end up sending a repaint event to
3480  // the widget if the window has been visible one before:
3481  [qt_mac_get_contentview_for(window) setNeedsDisplay:YES];
3482 #endif
3483  if(qt_mac_is_macsheet(q)) {
3485  } else if(qt_mac_is_macdrawer(q)) {
3486 #ifndef QT_MAC_USE_COCOA
3487  OpenDrawer(window, kWindowEdgeDefault, false);
3488 #else
3489  NSDrawer *drawer = qt_mac_drawer_for(q);
3490  [drawer openOnEdge:[drawer preferredEdge]];
3491 #endif
3492  } else {
3493 #ifndef QT_MAC_USE_COCOA
3494  ShowHide(window, true);
3495 #else
3496  // sync the opacity value back (in case of a fade).
3497  [window setAlphaValue:q->windowOpacity()];
3498 
3499  QWidget *top = 0;
3500  if (QApplicationPrivate::tryModalHelper(q, &top)) {
3501  if (q->testAttribute(Qt::WA_ShowWithoutActivating))
3502  [window orderFront:window];
3503  else
3504  [window makeKeyAndOrderFront:window];
3505  // If this window is app modal, we need to start spinning
3506  // a modal session for it. Interrupting
3507  // the event dispatcher will make this happend:
3510  } else {
3511  // The window is modally shaddowed, so we need to make
3512  // sure that we don't pop in front of the modal window:
3513  [window orderFront:window];
3515  if (NSWindow *modalWin = qt_mac_window_for(top))
3516  [modalWin orderFront:window];
3517  }
3518  }
3519  setSubWindowStacking(true);
3521 #endif
3522  if (q->windowType() == Qt::Popup) {
3523  qt_button_down = 0;
3524  if (q->focusWidget())
3525  q->focusWidget()->d_func()->setFocus_sys();
3526  else
3527  setFocus_sys();
3528  }
3529  toggleDrawers(true);
3530  }
3531  if (isCurrentlyMinimized) { //show in collapsed state
3532 #ifndef QT_MAC_USE_COCOA
3533  CollapseWindow(window, true);
3534 #else
3535  [window miniaturize:window];
3536 #endif
3537  } else if (!q->testAttribute(Qt::WA_ShowWithoutActivating)) {
3538 #ifndef QT_MAC_USE_COCOA
3540 #endif
3541  }
3542  } else if(topData()->embedded || !q->parentWidget() || q->parentWidget()->isVisible()) {
3543 #ifndef QT_MAC_USE_COCOA
3544  HIViewSetVisible(qt_mac_nativeview_for(q), true);
3545 #else
3546  if (NSView *view = qt_mac_nativeview_for(q)) {
3547  // INVARIANT: q is native. Just show the view:
3548  [view setHidden:NO];
3549  } else {
3550  // INVARIANT: q is alien. Update q instead:
3551  q->update();
3552  }
3553 #endif
3554  }
3555 
3556 #ifdef QT_MAC_USE_COCOA
3557  if ([NSApp isActive] && !qt_button_down && !QWidget::mouseGrabber()){
3558  // Update enter/leave immidiatly, don't wait for a move event. But only
3559  // if no grab exists (even if the grab points to this widget, it seems, ref X11)
3560  QPoint qlocal, qglobal;
3561  QWidget *widgetUnderMouse = 0;
3562  qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse);
3563  if (q == widgetUnderMouse) {
3564  QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, qt_last_mouse_receiver);
3565  qt_last_mouse_receiver = widgetUnderMouse;
3566  qt_last_native_mouse_receiver = widgetUnderMouse ?
3567  (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0;
3568  }
3569  }
3570 #endif
3571 
3572  topLevelAt_cache = 0;
3574 }
3575 
3577 {
3578 #ifndef QT_MAC_USE_COCOA
3579  CGPoint nativePoint = CGPointMake(pt.x(), pt.y());
3580  HIViewConvertPoint(&nativePoint, qt_mac_nativeview_for(child->parentWidget()),
3581  qt_mac_nativeview_for(child));
3582 #else
3583  NSPoint nativePoint = [qt_mac_nativeview_for(child) convertPoint:NSMakePoint(pt.x(), pt.y()) fromView:qt_mac_nativeview_for(child->parentWidget())];
3584 #endif
3585  return QPoint(nativePoint.x, nativePoint.y);
3586 }
3587 
3588 
3590 {
3591  Q_Q(QWidget);
3592  if((q->windowType() == Qt::Desktop)) //you can't hide the desktop!
3593  return;
3595  if(q->isWindow()) {
3596 #ifdef QT_MAC_USE_COCOA
3597  setSubWindowStacking(false);
3598 #endif
3600  if(qt_mac_is_macsheet(q)) {
3601 #ifndef QT_MAC_USE_COCOA
3602  WindowRef parent = 0;
3603  if(GetSheetWindowParent(window, &parent) != noErr || !parent)
3604  ShowHide(window, false);
3605  else
3606  HideSheetWindow(window);
3607 #else
3608  [NSApp endSheet:window];
3609  [window orderOut:window];
3610 #endif
3611  } else if(qt_mac_is_macdrawer(q)) {
3612 #ifndef QT_MAC_USE_COCOA
3613  CloseDrawer(window, false);
3614 #else
3615  [qt_mac_drawer_for(q) close];
3616 #endif
3617  } else {
3618 #ifndef QT_MAC_USE_COCOA
3619  ShowHide(window, false);
3620 #else
3621  // Only needed if it exists from 10.7 or later
3622  if ((q->windowType() == Qt::Tool) && [window respondsToSelector: @selector(setAnimationBehavior:)])
3623  [window setAnimationBehavior: 2]; // NSWindowAnimationBehaviorNone == 2
3624 
3625  [window orderOut:window];
3626  // Unfortunately it is not as easy as just hiding the window, we need
3627  // to find out if we were in full screen mode. If we were and this is
3628  // the last window in full screen mode then we need to unset the full screen
3629  // mode. If this is not the last visible window in full screen mode then we
3630  // don't change the full screen mode.
3631  if(q->isFullScreen())
3632  {
3633  bool keepFullScreen = false;
3634  QWidgetList windowList = qApp->topLevelWidgets();
3635  int windowCount = windowList.count();
3636  for(int i = 0; i < windowCount; i++)
3637  {
3638  QWidget *w = windowList[i];
3639  // If it is the same window, we don't need to check :-)
3640  if(q == w)
3641  continue;
3642  // If they are not visible or if they are minimized then
3643  // we just ignore them.
3644  if(!w->isVisible() || w->isMinimized())
3645  continue;
3646  // Is it full screen?
3647  // Notice that if there is one window in full screen mode then we
3648  // cannot switch the full screen mode off, therefore we just abort.
3649  if(w->isFullScreen()) {
3650  keepFullScreen = true;
3651  break;
3652  }
3653  }
3654  // No windows in full screen mode, so let just unset that flag.
3655  if(!keepFullScreen)
3657  }
3658 #endif
3659  toggleDrawers(false);
3661 #ifndef QT_MAC_USE_COCOA
3662  // Clear modality (because it seems something that we've always done).
3664  SetWindowModality(window, kWindowModalityNone,
3665  q->parentWidget() ? qt_mac_window_for(q->parentWidget()->window()) : 0);
3666  }
3667 #endif
3668  }
3669 #ifndef QT_MAC_USE_COCOA
3670  // If the window we now hide was the active window, we need
3671  // to find, and activate another window on screen. NB: Cocoa takes care of this
3672  // logic for us (and distinquishes between main windows and key windows)
3673  if (q->isActiveWindow() && !(q->windowType() == Qt::Popup)) {
3674  QWidget *w = 0;
3675  if(q->parentWidget())
3676  w = q->parentWidget()->window();
3677  if(!w || (!w->isVisible() && !w->isMinimized())) {
3678  for (WindowPtr wp = GetFrontWindowOfClass(kMovableModalWindowClass, true);
3679  wp; wp = GetNextWindowOfClass(wp, kMovableModalWindowClass, true)) {
3680  if((w = qt_mac_find_window(wp)))
3681  break;
3682  }
3683  if (!w){
3684  for (WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
3685  wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
3686  if((w = qt_mac_find_window(wp)))
3687  break;
3688  }
3689  }
3690  if (!w){
3691  for(WindowPtr wp = GetFrontWindowOfClass(kSimpleWindowClass, true);
3692  wp; wp = GetNextWindowOfClass(wp, kSimpleWindowClass, true)) {
3693  if((w = qt_mac_find_window(wp)))
3694  break;
3695  }
3696  }
3697  }
3698  if(w && w->isVisible() && !w->isMinimized()) {
3700  }
3701  }
3702 #endif
3703  } else {
3704  invalidateBuffer(q->rect());
3705 #ifndef QT_MAC_USE_COCOA
3706  HIViewSetVisible(qt_mac_nativeview_for(q), false);
3707 #else
3708  if (NSView *view = qt_mac_nativeview_for(q)) {
3709  // INVARIANT: q is native. Just hide the view:
3710  [view setHidden:YES];
3711  } else {
3712  // INVARIANT: q is alien. Repaint where q is placed instead:
3714  }
3715 #endif
3716  }
3717 
3718 #ifdef QT_MAC_USE_COCOA
3719  if ([NSApp isActive] && !qt_button_down && !QWidget::mouseGrabber()){
3720  // Update enter/leave immidiatly, don't wait for a move event. But only
3721  // if no grab exists (even if the grab points to this widget, it seems, ref X11)
3722  QPoint qlocal, qglobal;
3723  QWidget *widgetUnderMouse = 0;
3724  qt_mac_getTargetForMouseEvent(0, QEvent::Leave, qlocal, qglobal, 0, &widgetUnderMouse);
3725  if (q == widgetUnderMouse) {
3726  QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, qt_last_native_mouse_receiver);
3727  qt_last_mouse_receiver = widgetUnderMouse;
3728  qt_last_native_mouse_receiver = widgetUnderMouse ?
3729  (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0;
3730  }
3731  }
3732 #endif
3733 
3734  topLevelAt_cache = 0;
3738 }
3739 
3740 void QWidget::setWindowState(Qt::WindowStates newstate)
3741 {
3742  Q_D(QWidget);
3743  bool needShow = false;
3744  Qt::WindowStates oldstate = windowState();
3745  if (oldstate == newstate)
3746  return;
3747 
3748 #ifdef QT_MAC_USE_COCOA
3750 #endif
3751  bool needSendStateChange = true;
3752  if(isWindow()) {
3753  if((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
3754  if(newstate & Qt::WindowFullScreen) {
3755  if(QTLWExtra *tlextra = d->topData()) {
3756  if(tlextra->normalGeometry.width() < 0) {
3757  if(!testAttribute(Qt::WA_Resized))
3758  adjustSize();
3759  tlextra->normalGeometry = geometry();
3760  }
3761  tlextra->savedFlags = windowFlags();
3762  }
3763  needShow = isVisible();
3764  const QRect fullscreen(qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(this)));
3765  setParent(parentWidget(), Qt::Window | Qt::FramelessWindowHint | (windowFlags() & 0xffff0000)); //save
3766  setGeometry(fullscreen);
3767  if(!qApp->desktop()->screenNumber(this))
3769  } else {
3770  needShow = isVisible();
3771  if(!qApp->desktop()->screenNumber(this))
3773  setParent(parentWidget(), d->topData()->savedFlags);
3774  setGeometry(d->topData()->normalGeometry);
3775  d->topData()->normalGeometry.setRect(0, 0, -1, -1);
3776  }
3777  }
3778 
3779  d->createWinId();
3780 
3782  if((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
3783  if (newstate & Qt::WindowMinimized) {
3784 #ifndef QT_MAC_USE_COCOA
3785  CollapseWindow(window, true);
3786 #else
3787  [window miniaturize:window];
3788 #endif
3789  } else {
3790 #ifndef QT_MAC_USE_COCOA
3791  CollapseWindow(window, false);
3792 #else
3793  [window deminiaturize:window];
3794 #endif
3795  }
3796  needSendStateChange = oldstate == windowState(); // Collapse didn't change our flags.
3797  }
3798 
3799  if((newstate & Qt::WindowMaximized) && !((newstate & Qt::WindowFullScreen))) {
3800  if(QTLWExtra *tlextra = d->topData()) {
3801  if(tlextra->normalGeometry.width() < 0) {
3802  if(!testAttribute(Qt::WA_Resized))
3803  adjustSize();
3804  tlextra->normalGeometry = geometry();
3805  }
3806  }
3807  } else if(!(newstate & Qt::WindowFullScreen)) {
3808 // d->topData()->normalGeometry = QRect(0, 0, -1, -1);
3809  }
3810 
3811 #ifdef DEBUG_WINDOW_STATE
3812 #define WSTATE(x) qDebug("%s -- %s --> %s", #x, (oldstate & x) ? "true" : "false", (newstate & x) ? "true" : "false")
3813  WSTATE(Qt::WindowMinimized);
3814  WSTATE(Qt::WindowMaximized);
3815  WSTATE(Qt::WindowFullScreen);
3816 #undef WSTATE
3817 #endif
3818  if(!(newstate & (Qt::WindowMinimized|Qt::WindowFullScreen)) &&
3819  ((oldstate & Qt::WindowFullScreen) || (oldstate & Qt::WindowMinimized) ||
3820  (oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized))) {
3821  if(newstate & Qt::WindowMaximized) {
3822  data->fstrut_dirty = true;
3823 #ifndef QT_MAC_USE_COCOA
3824  HIToolbarRef toolbarRef;
3825  if (GetWindowToolbar(window, &toolbarRef) == noErr && toolbarRef
3826  && !isVisible() && !IsWindowToolbarVisible(window)) {
3827  // HIToolbar, needs to be shown so that it's in the structure window
3828  // Typically this is part of a main window and will get shown
3829  // during the show, but it's will make the maximize all wrong.
3830  ShowHideWindowToolbar(window, true, false);
3831  d->updateFrameStrut(); // In theory the dirty would work, but it's optimized out if the window is not visible :(
3832  }
3833  Rect bounds;
3835  QRect avail = dsk->availableGeometry(dsk->screenNumber(this));
3836  SetRect(&bounds, avail.x(), avail.y(), avail.x() + avail.width(), avail.y() + avail.height());
3837  if(QWExtra *extra = d->extraData()) {
3838  if(bounds.right - bounds.left > extra->maxw)
3839  bounds.right = bounds.left + extra->maxw;
3840  if(bounds.bottom - bounds.top > extra->maxh)
3841  bounds.bottom = bounds.top + extra->maxh;
3842  }
3843  if(d->topData()) {
3844  QRect fs = d->frameStrut();
3845  bounds.left += fs.left();
3846  if(bounds.right < avail.x()+avail.width())
3847  bounds.right = qMin<short>((uint)avail.x()+avail.width(), bounds.right+fs.left());
3848  if(bounds.bottom < avail.y()+avail.height())
3849  bounds.bottom = qMin<short>((uint)avail.y()+avail.height(), bounds.bottom+fs.top());
3850  bounds.top += fs.top();
3851  bounds.right -= fs.right();
3852  bounds.bottom -= fs.bottom();
3853  }
3854  QRect orect(geometry().x(), geometry().y(), width(), height()),
3855  nrect(bounds.left, bounds.top, bounds.right - bounds.left,
3856  bounds.bottom - bounds.top);
3857  if(orect != nrect) { // the new rect differ from the old
3858  Point idealSize = { nrect.height(), nrect.width() };
3859  ZoomWindowIdeal(window, inZoomOut, &idealSize);
3860  }
3861 #else
3862  NSToolbar *toolbarRef = [window toolbar];
3863  if (toolbarRef && !isVisible() && ![toolbarRef isVisible]) {
3864  // HIToolbar, needs to be shown so that it's in the structure window
3865  // Typically this is part of a main window and will get shown
3866  // during the show, but it's will make the maximize all wrong.
3867  // ### Not sure this is right for NSToolbar...
3868  [toolbarRef setVisible:true];
3869 // ShowHideWindowToolbar(window, true, false);
3870  d->updateFrameStrut(); // In theory the dirty would work, but it's optimized out if the window is not visible :(
3871  }
3872  // Everything should be handled by Cocoa.
3873  if (!windowFlags() & Qt::FramelessWindowHint) {
3874  [window zoom:window];
3875  } else {
3877  QRect avail = dsk->availableGeometry(dsk->screenNumber(this));
3878  setGeometry(avail);
3879  }
3880 
3881 #endif
3882  needSendStateChange = oldstate == windowState(); // Zoom didn't change flags.
3883  } else if(oldstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen)) {
3884 #ifndef QT_MAC_USE_COCOA
3885  Point idealSize;
3886  ZoomWindowIdeal(window, inZoomIn, &idealSize);
3887 #else
3888  [window zoom:window];
3889 #endif
3890  if(QTLWExtra *tlextra = d->topData()) {
3891  setGeometry(tlextra->normalGeometry);
3892  tlextra->normalGeometry.setRect(0, 0, -1, -1);
3893  }
3894  }
3895  }
3896  }
3897 
3898  data->window_state = newstate;
3899 
3900  if(needShow)
3901  show();
3902 
3903  if(newstate & Qt::WindowActive)
3904  activateWindow();
3905 
3907  if (needSendStateChange) {
3908  QWindowStateChangeEvent e(oldstate);
3909  QApplication::sendEvent(this, &e);
3910  }
3911 }
3912 
3914 {
3915  Q_Q(QWidget);
3916  if (q->testAttribute(Qt::WA_WState_Created)) {
3917 #ifdef QT_MAC_USE_COCOA
3919  NSView *view = qt_mac_effectiveview_for(q);
3920  [[view window] makeFirstResponder:view];
3921 #else
3922  SetKeyboardFocus(qt_mac_window_for(q), qt_mac_nativeview_for(q), 1);
3923 #endif
3924  }
3925 }
3926 
3927 NSComparisonResult compareViews2Raise(id view1, id view2, void *context)
3928 {
3929  id topView = reinterpret_cast<id>(context);
3930  if (view1 == topView)
3931  return NSOrderedDescending;
3932  if (view2 == topView)
3933  return NSOrderedAscending;
3934  return NSOrderedSame;
3935 }
3936 
3938 {
3939  Q_Q(QWidget);
3940  if((q->windowType() == Qt::Desktop))
3941  return;
3942 
3943 #if QT_MAC_USE_COCOA
3945  if (isRealWindow()) {
3946  // With the introduction of spaces it is not as simple as just raising the window.
3947  // First we need to check if we are in the right space. If we are, then we just continue
3948  // as usual. The problem comes when we are not in the active space. There are two main cases:
3949  // 1. Our parent was moved to a new space. In this case we want the window to be raised
3950  // in the same space as its parent.
3951  // 2. We don't have a parent. For this case we will just raise the window and let Cocoa
3952  // switch to the corresponding space.
3953  // NOTICE: There are a lot of corner cases here. We are keeping this simple for now, if
3954  // required we will introduce special handling for some of them.
3955  if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) {
3957  // isOnActiveSpace is available only from 10.6 onwards, so we need to check if it is
3958  // available before calling it.
3959  if([window respondsToSelector:@selector(isOnActiveSpace)]) {
3960  if(![window performSelector:@selector(isOnActiveSpace)]) {
3962  if(parentWidget) {
3963  OSWindowRef parentWindow = qt_mac_window_for(parentWidget);
3964  if(parentWindow && [parentWindow respondsToSelector:@selector(isOnActiveSpace)]) {
3965  if ([parentWindow performSelector:@selector(isOnActiveSpace)]) {
3966  // The window was created in a different space. Therefore if we want
3967  // to show it in the current space we need to recreate it in the new
3968  // space.
3969  recreateMacWindow();
3970  window = qt_mac_window_for(q);
3971  }
3972  }
3973  }
3974  }
3975  }
3976  [window orderFront:window];
3977  }
3978  if (qt_mac_raise_process) { //we get to be the active process now
3979  ProcessSerialNumber psn;
3980  GetCurrentProcess(&psn);
3981  SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
3982  }
3983  } else {
3984  NSView *view = qt_mac_nativeview_for(q);
3985  NSView *parentView = [view superview];
3986  [parentView sortSubviewsUsingFunction:compareViews2Raise context:reinterpret_cast<void *>(view)];
3987  }
3988  topLevelAt_cache = 0;
3989 #else
3990  if(q->isWindow()) {
3991  //raise this window
3992  BringToFront(qt_mac_window_for(q));
3993  if(qt_mac_raise_process) { //we get to be the active process now
3994  ProcessSerialNumber psn;
3995  GetCurrentProcess(&psn);
3996  SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
3997  }
3998  } else if(q->parentWidget()) {
3999  HIViewSetZOrder(qt_mac_nativeview_for(q), kHIViewZOrderAbove, 0);
4001  }
4002 #endif
4003 }
4004 
4005 NSComparisonResult compareViews2Lower(id view1, id view2, void *context)
4006 {
4007  id topView = reinterpret_cast<id>(context);
4008  if (view1 == topView)
4009  return NSOrderedAscending;
4010  if (view2 == topView)
4011  return NSOrderedDescending;
4012  return NSOrderedSame;
4013 }
4014 
4016 {
4017  Q_Q(QWidget);
4018  if((q->windowType() == Qt::Desktop))
4019  return;
4020 #ifdef QT_MAC_USE_COCOA
4021  if (isRealWindow()) {
4023  [window orderBack:window];
4024  } else {
4025  NSView *view = qt_mac_nativeview_for(q);
4026  NSView *parentView = [view superview];
4027  [parentView sortSubviewsUsingFunction:compareViews2Lower context:reinterpret_cast<void *>(view)];
4028  }
4029  topLevelAt_cache = 0;
4030 #else
4031  if(q->isWindow()) {
4032  SendBehind(qt_mac_window_for(q), 0);
4033  } else if(q->parentWidget()) {
4034  invalidateBuffer(q->rect());
4035  HIViewSetZOrder(qt_mac_nativeview_for(q), kHIViewZOrderBelow, 0);
4037  }
4038 #endif
4039 }
4040 
4041 NSComparisonResult compareViews2StackUnder(id view1, id view2, void *context)
4042 {
4043  const QHash<NSView *, int> &viewOrder = *reinterpret_cast<QHash<NSView *, int> *>(context);
4044  if (viewOrder[view1] < viewOrder[view2])
4045  return NSOrderedAscending;
4046  if (viewOrder[view1] > viewOrder[view2])
4047  return NSOrderedDescending;
4048  return NSOrderedSame;
4049 }
4050 
4052 {
4053  // stackUnder
4054  Q_Q(QWidget);
4055  if(!w || q->isWindow() || (q->windowType() == Qt::Desktop))
4056  return;
4057 #ifdef QT_MAC_USE_COCOA
4058  // Do the same trick as lower_sys() and put this widget before the widget passed in.
4059  NSView *myView = qt_mac_nativeview_for(q);
4060  NSView *wView = qt_mac_nativeview_for(w);
4061 
4062  QHash<NSView *, int> viewOrder;
4063  NSView *parentView = [myView superview];
4064  NSArray *subviews = [parentView subviews];
4065  NSUInteger index = 1;
4066  // make a hash of view->zorderindex and make sure z-value is always odd,
4067  // so that when we modify the order we create a new (even) z-value which
4068  // will not interfere with others.
4069  for (NSView *subview in subviews) {
4070  viewOrder.insert(subview, index * 2);
4071  ++index;
4072  }
4073  viewOrder[myView] = viewOrder[wView] - 1;
4074 
4075  [parentView sortSubviewsUsingFunction:compareViews2StackUnder context:reinterpret_cast<void *>(&viewOrder)];
4076 #else
4077  QWidget *p = q->parentWidget();
4078  if(!p || p != w->parentWidget())
4079  return;
4080  invalidateBuffer(q->rect());
4081  HIViewSetZOrder(qt_mac_nativeview_for(q), kHIViewZOrderBelow, qt_mac_nativeview_for(w));
4083 #endif
4084 }
4085 
4086 #ifndef QT_MAC_USE_COCOA
4087 /*
4088  Modifies the bounds for a widgets backing HIView during moves and resizes. Also updates the
4089  widget, either by scrolling its contents or repainting, depending on the WA_StaticContents
4090  flag
4091 */
4092 static void qt_mac_update_widget_position(QWidget *q, QRect oldRect, QRect newRect)
4093 {
4094  HIRect bounds = CGRectMake(newRect.x(), newRect.y(),
4095  newRect.width(), newRect.height());
4096 
4097  const HIViewRef view = qt_mac_nativeview_for(q);
4098  const bool isMove = (oldRect.topLeft() != newRect.topLeft());
4099  const bool isResize = (oldRect.size() != newRect.size());
4100 
4101 // qDebug() << oldRect << newRect << isMove << isResize << q->testAttribute(Qt::WA_OpaquePaintEvent) << q->testAttribute(Qt::WA_StaticContents);
4103 
4104  // Perform a normal (complete repaint) update in some cases:
4105  if (
4106  // always repaint on move.
4107  (isMove) ||
4108 
4109  // limited update on resize requires WA_StaticContents.
4110  (isResize && q->testAttribute(Qt::WA_StaticContents) == false) ||
4111 
4112  // one of the rects are invalid
4113  (oldRect.isValid() == false || newRect.isValid() == false) ||
4114 
4115  // the position update is a part of a drag-and-drop operation
4117 
4118  // we are on Panther (no HIViewSetNeedsDisplayInRect)
4120  ){
4121  HIViewSetFrame(view, &bounds);
4122  return;
4123  }
4124 
4125  const int dx = newRect.x() - oldRect.x();
4126  const int dy = newRect.y() - oldRect.y();
4127 
4128  if (isMove) {
4129  // HIViewScrollRect silently fails if we try to scroll anything under the grow box.
4130  // Check if there's one present within the widget rect, and if there is fall back
4131  // to repainting the entire widget.
4132  QWidget const * const parentWidget = q->parentWidget();
4133  const HIViewRef parentView = qt_mac_nativeview_for(parentWidget);
4134  HIViewRef nativeSizeGrip = 0;
4136  HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(q->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip);
4137  if (nativeSizeGrip) {
4138  QWidget * const window = q->window();
4139 
4140  const int sizeGripSize = 20;
4141  const QRect oldWidgetRect = QRect(q->mapTo(window, QPoint(0, 0)), QSize(oldRect.width(), oldRect.height()));
4142  const QRect newWidgetRect = QRect(q->mapTo(window, QPoint(0, 0)), QSize(newRect.width(), newRect.height()));
4143  const QRect sizeGripRect = QRect(window->rect().bottomRight() - QPoint(sizeGripSize, sizeGripSize),
4144  window->rect().bottomRight());
4145 
4146  if (sizeGripRect.intersects(oldWidgetRect) || sizeGripRect.intersects(newWidgetRect)) {
4147  HIViewSetFrame(view, &bounds);
4148  return;
4149  }
4150  }
4151 
4152  // Don't scroll anything outside the parent widget rect.
4153  const QRect scrollRect = (oldRect | newRect) & parentWidget->rect();
4154  const HIRect scrollBounds =
4155  CGRectMake(scrollRect.x(), scrollRect.y(), scrollRect.width(), scrollRect.height());
4156 
4157  // We cannot scroll when the widget has a mask as that would
4158  // scroll the masked out areas too
4159  if (qd->extra && qd->extra->hasMask) {
4160  HIViewMoveBy(view, dx, dy);
4161  return;
4162  }
4163 
4164  OSStatus err = HIViewScrollRect(parentView, &scrollBounds, dx, dy);
4165  if (err != noErr) {
4166  HIViewSetNeedsDisplay(view, true);
4167  qWarning("QWidget: Internal error (%s:%d)", __FILE__, __LINE__);
4168  }
4169  }
4170  // Set the view bounds with drawing disabled to prevent repaints.
4171  HIViewSetDrawingEnabled(view, false);
4172  HIViewSetFrame(view, &bounds);
4173  HIViewSetDrawingEnabled(view, true);
4174 
4175  // Update any newly exposed areas due to resizing.
4176  const int startx = oldRect.width();
4177  const int stopx = newRect.width();
4178  const int starty = oldRect.height();
4179  const int stopy = newRect.height();
4180 
4181  const HIRect verticalSlice = CGRectMake(startx, 0, stopx , stopy);
4182  HIViewSetNeedsDisplayInRect(view, &verticalSlice, true);
4183  const HIRect horizontalSlice = CGRectMake(0, starty, startx, stopy);
4184  HIViewSetNeedsDisplayInRect(view, &horizontalSlice, true);
4185 }
4186 #endif
4187 
4188 /*
4189  Helper function for non-toplevel widgets. Helps to map Qt's 32bit
4190  coordinate system to OS X's 16bit coordinate system.
4191 
4192  Sets the geometry of the widget to data.crect, but clipped to sizes
4193  that OS X can handle. Unmaps widgets that are completely outside the
4194  valid range.
4195 
4196  Maintains data.wrect, which is the geometry of the OS X widget,
4197  measured in this widget's coordinate system.
4198 
4199  if the parent is not clipped, parentWRect is empty, otherwise
4200  parentWRect is the geometry of the parent's OS X rect, measured in
4201  parent's coord sys
4202 */
4203 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
4204 {
4205  Q_Q(QWidget);
4206  Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
4207 
4208  if (!q->internalWinId() && QApplicationPrivate::graphicsSystem() != 0) {
4209  // We have no view to move, and no paint engine that
4210  // we can update dirty regions on. So just return:
4211  return;
4212  }
4213 
4215 
4216  /*
4217  There are up to four different coordinate systems here:
4218  Qt coordinate system for this widget.
4219  X coordinate system for this widget (relative to wrect).
4220  Qt coordinate system for parent
4221  X coordinate system for parent (relative to parent's wrect).
4222  */
4223 
4224  // wrect is the same as crect, except that it is
4225  // clipped to fit inside parent (and screen):
4226  QRect wrect;
4227 
4228  // wrectInParentCoordSys will be the same as wrect, except that it is
4229  // originated in q's parent rather than q itself. It starts out in
4230  // parent's Qt coord system, and ends up in parent's coordinate system:
4231  QRect wrectInParentCoordSys = data.crect;
4232 
4233  // If q's parent has been clipped, parentWRect will
4234  // be filled with the parents clipped crect:
4235  QRect parentWRect;
4236 
4237  // Embedded have different meaning on each platform, and on
4238  // Mac, it means that q is a QMacNativeWidget.
4239  bool isEmbeddedWindow = (q->isWindow() && topData()->embedded);
4240 #ifdef QT_MAC_USE_COCOA
4241  NSView *nsview = qt_mac_nativeview_for(q);
4242 #endif
4243  if (!isEmbeddedWindow) {
4244  parentWRect = q->parentWidget()->data->wrect;
4245  } else {
4246  // INVARIANT: q's parent view is not owned by Qt. So we need to
4247  // do some extra calls to get the clipped rect of the parent view:
4248 #ifndef QT_MAC_USE_COCOA
4249  HIViewRef parentView = HIViewGetSuperview(qt_mac_nativeview_for(q));
4250 #else
4251  NSView *parentView = [qt_mac_nativeview_for(q) superview];
4252 #endif
4253  if (parentView) {
4254 #ifndef QT_MAC_USE_COCOA
4255  HIRect tmpRect;
4256  HIViewGetFrame(parentView, &tmpRect);
4257 #else
4258  NSRect tmpRect = [parentView frame];
4259 #endif
4260  parentWRect = QRect(tmpRect.origin.x, tmpRect.origin.y,
4261  tmpRect.size.width, tmpRect.size.height);
4262  } else {
4263  const QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
4264  parentWRect = wrectRange;
4265  }
4266  }
4267 
4268  if (parentWRect.isValid()) {
4269  // INVARIANT: q's parent has been clipped.
4270  // So we fit our own wrects inside it:
4271  if (!parentWRect.contains(wrectInParentCoordSys) && !isEmbeddedWindow) {
4272  wrectInParentCoordSys &= parentWRect;
4273  wrect = wrectInParentCoordSys;
4274  // Make sure wrect is originated in q's coordinate system:
4275  wrect.translate(-data.crect.topLeft());
4276  }
4277  // // Make sure wrectInParentCoordSys originated in q's parent coordinate system:
4278  wrectInParentCoordSys.translate(-parentWRect.topLeft());
4279  } else {
4280  // INVARIANT: we dont know yet the clipping rect of q's parent.
4281  // So we may or may not have to adjust our wrects:
4282 
4283  if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
4284  // This is where the main optimization is: we have an old wrect from an earlier
4285  // setGeometry call, and the new crect is smaller than it. If the final wrect is
4286  // also inside the old wrect, we can just move q and its children to the new
4287  // location without any clipping:
4288 
4289  // vrect will be the part of q that's will be visible inside
4290  // q's parent. If it inside the old wrect, then we can just move:
4291  QRect vrect = wrectInParentCoordSys & q->parentWidget()->rect();
4292  vrect.translate(-data.crect.topLeft());
4293 
4294  if (data.wrect.contains(vrect)) {
4295  wrectInParentCoordSys = data.wrect;
4296  wrectInParentCoordSys.translate(data.crect.topLeft());
4297 #ifndef QT_MAC_USE_COCOA
4298  HIRect bounds = CGRectMake(wrectInParentCoordSys.x(), wrectInParentCoordSys.y(),
4299  wrectInParentCoordSys.width(), wrectInParentCoordSys.height());
4300  HIViewSetFrame(qt_mac_nativeview_for(q), &bounds);
4301 #else
4302  if (nsview) {
4303  // INVARIANT: q is native. Set view frame:
4304  NSRect bounds = NSMakeRect(wrectInParentCoordSys.x(), wrectInParentCoordSys.y(),
4305  wrectInParentCoordSys.width(), wrectInParentCoordSys.height());
4306  [nsview setFrame:bounds];
4307  } else {
4308  // INVARIANT: q is alien. Repaint wrect instead (includes old and new wrect):
4309  QWidget *parent = q->parentWidget();
4310  QPoint globalPosWRect = parent->mapToGlobal(data.wrect.topLeft());
4311 
4312  QWidget *nativeParent = q->nativeParentWidget();
4313  QRect dirtyWRect = QRect(nativeParent->mapFromGlobal(globalPosWRect), data.wrect.size());
4314 
4315  nativeParent->update(dirtyWRect);
4316  }
4317 #endif
4318  if (q->testAttribute(Qt::WA_OutsideWSRange)) {
4319  q->setAttribute(Qt::WA_OutsideWSRange, false);
4320  if (!dontShow) {
4321  q->setAttribute(Qt::WA_Mapped);
4322 #ifndef QT_MAC_USE_COCOA
4323  HIViewSetVisible(qt_mac_nativeview_for(q), true);
4324 #else
4325  // If q is Alien, the following call does nothing:
4326  [nsview setHidden:NO];
4327 #endif
4328  }
4329  }
4330  return;
4331  }
4332  }
4333 
4334 #ifndef QT_MAC_USE_COCOA
4335  const QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
4336  if (!validRange.contains(wrectInParentCoordSys)) {
4337  // We're too big, and must clip:
4338  QPoint screenOffset(0, 0); // offset of the part being on screen
4339  const QWidget *parentWidget = q->parentWidget();
4340  while (parentWidget && !parentWidget->isWindow()) {
4341  screenOffset -= parentWidget->data->crect.topLeft();
4342  parentWidget = parentWidget->parentWidget();
4343  }
4344  QRect cropRect(screenOffset.x() - WRECT_MAX,
4345  screenOffset.y() - WRECT_MAX,
4346  2*WRECT_MAX,
4347  2*WRECT_MAX);
4348 
4349  wrectInParentCoordSys &=cropRect;
4350  wrect = wrectInParentCoordSys;
4351  wrect.translate(-data.crect.topLeft());
4352  }
4353 #endif //QT_MAC_USE_COCOA
4354  }
4355 
4356  // unmap if we are outside the valid window system coord system
4357  bool outsideRange = !wrectInParentCoordSys.isValid();
4358  bool mapWindow = false;
4359  if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
4360  q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
4361  if (outsideRange) {
4362 #ifndef QT_MAC_USE_COCOA
4363  HIViewSetVisible(qt_mac_nativeview_for(q), false);
4364 #else
4365  // If q is Alien, the following call does nothing:
4366  [nsview setHidden:YES];
4367 #endif
4368  q->setAttribute(Qt::WA_Mapped, false);
4369  } else if (!q->isHidden()) {
4370  mapWindow = true;
4371  }
4372  }
4373 
4374  if (outsideRange)
4375  return;
4376 
4377  // Store the new clipped rect:
4378  bool jump = (data.wrect != wrect);
4379  data.wrect = wrect;
4380 
4381  // and now recursively for all children...
4382  // ### can be optimized
4383  for (int i = 0; i < children.size(); ++i) {
4384  QObject *object = children.at(i);
4385  if (object->isWidgetType()) {
4386  QWidget *w = static_cast<QWidget *>(object);
4387  if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
4388  w->d_func()->setWSGeometry();
4389  }
4390  }
4391 
4392 #ifndef QT_MAC_USE_COCOA
4393  // Move the actual HIView:
4394  qt_mac_update_widget_position(q, oldRect, wrectInParentCoordSys);
4395  if (jump)
4396  q->update();
4397 #else
4398  if (nsview) {
4399  // INVARIANT: q is native. Move the actual NSView:
4400  NSRect bounds = NSMakeRect(
4401  wrectInParentCoordSys.x(), wrectInParentCoordSys.y(),
4402  wrectInParentCoordSys.width(), wrectInParentCoordSys.height());
4403  [nsview setFrame:bounds];
4404  if (jump)
4405  q->update();
4406  } else if (QApplicationPrivate::graphicsSystem() == 0){
4407  // INVARIANT: q is alien and we use native paint engine.
4408  // Schedule updates where q is moved from and to:
4409  const QWidget *parent = q->parentWidget();
4410  const QPoint globalPosOldWRect = parent->mapToGlobal(oldRect.topLeft());
4411  const QPoint globalPosNewWRect = parent->mapToGlobal(wrectInParentCoordSys.topLeft());
4412 
4413  QWidget *nativeParent = q->nativeParentWidget();
4414  const QRegion dirtyOldWRect = QRect(nativeParent->mapFromGlobal(globalPosOldWRect), oldRect.size());
4415  const QRegion dirtyNewWRect = QRect(nativeParent->mapFromGlobal(globalPosNewWRect), wrectInParentCoordSys.size());
4416 
4417  const bool sizeUnchanged = oldRect.size() == wrectInParentCoordSys.size();
4418  const bool posUnchanged = oldRect.topLeft() == wrectInParentCoordSys.topLeft();
4419 
4420  // Resolve/minimize the region that needs to update:
4421  if (sizeUnchanged && q->testAttribute(Qt::WA_OpaquePaintEvent)) {
4422  // INVARIANT: q is opaque, and is only moved (not resized). So in theory we only
4423  // need to blit pixels, and skip a repaint. But we can only make this work if we
4424  // had access to the backbuffer, so we need to update all:
4425  nativeParent->update(dirtyOldWRect | dirtyNewWRect);
4426  } else if (posUnchanged && q->testAttribute(Qt::WA_StaticContents)) {
4427  // We only need to redraw exposed areas:
4428  nativeParent->update(dirtyNewWRect - dirtyOldWRect);
4429  } else {
4430  nativeParent->update(dirtyOldWRect | dirtyNewWRect);
4431  }
4432  }
4433 #endif
4434 
4435  if (mapWindow && !dontShow) {
4436  q->setAttribute(Qt::WA_Mapped);
4437 #ifndef QT_MAC_USE_COCOA
4438  HIViewSetVisible(qt_mac_nativeview_for(q), true);
4439 #else
4440  // If q is Alien, the following call does nothing:
4441  [nsview setHidden:NO];
4442 #endif
4443  }
4444 }
4445 
4446 void QWidgetPrivate::adjustWithinMaxAndMinSize(int &w, int &h)
4447 {
4448  if (QWExtra *extra = extraData()) {
4449  w = qMin(w, extra->maxw);
4450  h = qMin(h, extra->maxh);
4451  w = qMax(w, extra->minw);
4452  h = qMax(h, extra->minh);
4453 
4454  // Deal with size increment
4455  if (QTLWExtra *top = topData()) {
4456  if(top->incw) {
4457  w = w/top->incw;
4458  w *= top->incw;
4459  }
4460  if(top->inch) {
4461  h = h/top->inch;
4462  h *= top->inch;
4463  }
4464  }
4465  }
4466 
4467  if (isRealWindow()) {
4468  w = qMax(0, w);
4469  h = qMax(0, h);
4470  }
4471 }
4472 
4473 void QWidgetPrivate::applyMaxAndMinSizeOnWindow()
4474 {
4475  Q_Q(QWidget);
4477 
4478  const float max_f(20000);
4479 #ifndef QT_MAC_USE_COCOA
4480 #define SF(x) ((x > max_f) ? max_f : x)
4481  HISize max = CGSizeMake(SF(extra->maxw), SF(extra->maxh));
4482  HISize min = CGSizeMake(SF(extra->minw), SF(extra->minh));
4483 #undef SF
4484  SetWindowResizeLimits(qt_mac_window_for(q), &min, &max);
4485 #else
4486 #define SF(x) ((x > max_f) ? max_f : x)
4487  NSSize max = NSMakeSize(SF(extra->maxw), SF(extra->maxh));
4488  NSSize min = NSMakeSize(SF(extra->minw), SF(extra->minh));
4489 #undef SF
4490  [qt_mac_window_for(q) setContentMinSize:min];
4491  [qt_mac_window_for(q) setContentMaxSize:max];
4492 #endif
4493 }
4494 
4495 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
4496 {
4497  Q_Q(QWidget);
4498  Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
4499 
4500  if(q->windowType() == Qt::Desktop)
4501  return;
4502 
4504  bool realWindow = isRealWindow();
4505 
4506  if (realWindow && !q->testAttribute(Qt::WA_DontShowOnScreen)){
4507  adjustWithinMaxAndMinSize(w, h);
4508 #ifndef QT_MAC_USE_COCOA
4509  if (w != 0 && h != 0) {
4510  topData()->isSetGeometry = 1;
4511  topData()->isMove = isMove;
4512  Rect r; SetRect(&r, x, y, x + w, y + h);
4513  SetWindowBounds(qt_mac_window_for(q), kWindowContentRgn, &r);
4514  topData()->isSetGeometry = 0;
4515  } else {
4516  setGeometry_sys_helper(x, y, w, h, isMove);
4517  }
4518 #else
4519  if (!isMove && !q->testAttribute(Qt::WA_Moved) && !q->isVisible()) {
4520  // INVARIANT: The location of the window has not yet been set. The default will
4521  // instead be to center it on the desktop, or over the parent, if any. Since we now
4522  // resize the window, we need to adjust the top left position to keep the window
4523  // centeralized. And we need to to this now (and before show) in case the positioning
4524  // of other windows (e.g. sub-windows) depend on this position:
4525  if (QWidget *p = q->parentWidget()) {
4526  x = p->geometry().center().x() - (w / 2);
4527  y = p->geometry().center().y() - (h / 2);
4528  } else {
4530  x = availGeo.center().x() - (w / 2);
4531  y = availGeo.center().y() - (h / 2);
4532  }
4533  }
4534 
4535  QSize olds = q->size();
4536  const bool isResize = (olds != QSize(w, h));
4537  NSWindow *window = qt_mac_window_for(q);
4538  const QRect &fStrut = frameStrut();
4539  const QRect frameRect(QPoint(x - fStrut.left(), y - fStrut.top()),
4540  QSize(fStrut.left() + fStrut.right() + w,
4541  fStrut.top() + fStrut.bottom() + h));
4542  NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1),
4543  frameRect.width(), frameRect.height());
4544  // The setFrame call will trigger a 'windowDidResize' notification for the corresponding
4545  // NSWindow. The pending flag is set, so that the resize event can be send as non-spontaneous.
4546  if (isResize)
4547  q->setAttribute(Qt::WA_PendingResizeEvent);
4548  QPoint currTopLeft = data.crect.topLeft();
4549  if (currTopLeft.x() == x && currTopLeft.y() == y
4550  && cocoaFrameRect.size.width != 0
4551  && cocoaFrameRect.size.height != 0) {
4552  [window setFrame:cocoaFrameRect display:realWindow];
4553  } else {
4554  // The window is moved and resized (or resized to zero).
4555  // Since Cocoa usually only sends us a resize callback after
4556  // setting a window frame, we issue an explicit move as
4557  // well. To stop Cocoa from optimize away the move (since the move
4558  // would have the same origin as the setFrame call) we shift the
4559  // window back and forth inbetween.
4560  cocoaFrameRect.origin.y += 1;
4561  [window setFrame:cocoaFrameRect display:realWindow];
4562  cocoaFrameRect.origin.y -= 1;
4563  [window setFrameOrigin:cocoaFrameRect.origin];
4564  }
4565 #endif
4566  } else {
4567  setGeometry_sys_helper(x, y, w, h, isMove);
4568  }
4569 
4570  topLevelAt_cache = 0;
4571 }
4572 
4573 void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isMove)
4574 {
4575  Q_Q(QWidget);
4576  bool realWindow = isRealWindow();
4577 
4578  QPoint oldp = q->pos();
4579  QSize olds = q->size();
4580  // Apply size restrictions, applicable for Windows & Widgets.
4581  if (QWExtra *extra = extraData()) {
4582  w = qBound(extra->minw, w, extra->maxw);
4583  h = qBound(extra->minh, h, extra->maxh);
4584  }
4585  const bool isResize = (olds != QSize(w, h));
4586 
4587  if (!realWindow && !isResize && QPoint(x, y) == oldp)
4588  return;
4589 
4590  if (isResize)
4592 
4593  const bool visible = q->isVisible();
4594  data.crect = QRect(x, y, w, h);
4595 
4596  if (realWindow) {
4597  adjustWithinMaxAndMinSize(w, h);
4598  qt_mac_update_sizer(q);
4599 
4600 #ifndef QT_MAC_USE_COCOA
4601  if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
4603  if (extra->maxw && extra->maxh && extra->maxw == extra->minw
4604  && extra->maxh == extra->minh) {
4605  ChangeWindowAttributes(window, kWindowNoAttributes, kWindowFullZoomAttribute);
4606  } else {
4607  ChangeWindowAttributes(window, kWindowFullZoomAttribute, kWindowNoAttributes);
4608  }
4609  }
4610  HIRect bounds = CGRectMake(0, 0, w, h);
4611  HIViewSetFrame(qt_mac_nativeview_for(q), &bounds);
4612 #else
4613  [qt_mac_nativeview_for(q) setFrame:NSMakeRect(0, 0, w, h)];
4614 #endif
4615  } else {
4616  const QRect oldRect(oldp, olds);
4617  if (!isResize && QApplicationPrivate::graphicsSystem())
4618  moveRect(oldRect, x - oldp.x(), y - oldp.y());
4619 
4620  setWSGeometry(false, oldRect);
4621 
4622  if (isResize && QApplicationPrivate::graphicsSystem())
4623  invalidateBuffer_resizeHelper(oldp, olds);
4624  }
4625 
4626  if(isMove || isResize) {
4627  if(!visible) {
4628  if(isMove && q->pos() != oldp)
4629  q->setAttribute(Qt::WA_PendingMoveEvent, true);
4630  if(isResize)
4631  q->setAttribute(Qt::WA_PendingResizeEvent, true);
4632  } else {
4633  if(isResize) { //send the resize event..
4634  QResizeEvent e(q->size(), olds);
4635  QApplication::sendEvent(q, &e);
4636  }
4637  if(isMove && q->pos() != oldp) { //send the move event..
4638  QMoveEvent e(q->pos(), oldp);
4639  QApplication::sendEvent(q, &e);
4640  }
4641  }
4642  }
4644 }
4645 
4647 {
4648  updateMaximizeButton_sys();
4649  applyMaxAndMinSizeOnWindow();
4650 }
4651 
4652 void QWidgetPrivate::updateMaximizeButton_sys()
4653 {
4654  Q_Q(QWidget);
4655  if (q->data->window_flags & Qt::CustomizeWindowHint)
4656  return;
4657 
4659  QTLWExtra * tlwExtra = topData();
4660 #ifdef QT_MAC_USE_COCOA
4662  NSButton *maximizeButton = [window standardWindowButton:NSWindowZoomButton];
4663 #endif
4664  if (extra->maxw && extra->maxh
4665  && extra->maxw == extra->minw
4666  && extra->maxh == extra->minh) {
4667  // The window has a fixed size, so gray out the maximize button:
4668  if (!tlwExtra->savedWindowAttributesFromMaximized) {
4669 #ifndef QT_MAC_USE_COCOA
4670  GetWindowAttributes(window,
4671  (WindowAttributes*)&extra->topextra->savedWindowAttributesFromMaximized);
4672 
4673 #else
4674  tlwExtra->savedWindowAttributesFromMaximized = (![maximizeButton isHidden] && [maximizeButton isEnabled]);
4675 #endif
4676  }
4677 #ifndef QT_MAC_USE_COCOA
4678  ChangeWindowAttributes(window, kWindowNoAttributes, kWindowFullZoomAttribute);
4679 #else
4680  [maximizeButton setEnabled:NO];
4681 #endif
4682 
4683 
4684  } else {
4685  if (tlwExtra->savedWindowAttributesFromMaximized) {
4686 #ifndef QT_MAC_USE_COCOA
4687  ChangeWindowAttributes(window,
4688  extra->topextra->savedWindowAttributesFromMaximized,
4689  kWindowNoAttributes);
4690 #else
4691  [maximizeButton setEnabled:YES];
4692 #endif
4693  tlwExtra->savedWindowAttributesFromMaximized = 0;
4694  }
4695  }
4696 
4697 
4698 }
4699 
4700 void QWidgetPrivate::scroll_sys(int dx, int dy)
4701 {
4703  // INVARIANT: Alien paint engine
4704  scrollChildren(dx, dy);
4705  scrollRect(q_func()->rect(), dx, dy);
4706  } else {
4707  scroll_sys(dx, dy, QRect());
4708  }
4709 }
4710 
4711 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &qscrollRect)
4712 {
4713  if (QMacScrollOptimization::delayScroll(this, dx, dy, qscrollRect))
4714  return;
4715 
4716  Q_Q(QWidget);
4718  // INVARIANT: Alien paint engine
4719  scrollRect(qscrollRect, dx, dy);
4720  return;
4721  }
4722 
4723  static int accelEnv = -1;
4724  if (accelEnv == -1) {
4725  accelEnv = qgetenv("QT_NO_FAST_SCROLL").toInt() == 0;
4726  }
4727 
4728  // Scroll the whole widget if qscrollRect is not valid:
4729  QRect validScrollRect = qscrollRect.isValid() ? qscrollRect : q->rect();
4730 
4731  // If q is overlapped by other widgets, we cannot just blit pixels since
4732  // this will move overlapping widgets as well. In case we just update:
4733  const bool overlapped = isOverlapped(validScrollRect.translated(data.crect.topLeft()));
4734  const bool accelerateScroll = accelEnv && isOpaque && !overlapped;
4735  const bool isAlien = (q->internalWinId() == 0);
4736 
4737  // If qscrollRect is valid, we are _not_ supposed to scroll q's children (as documented).
4738  // But we do scroll children (and the whole of q) if qscrollRect is invalid. This case is
4739  // documented as undefined, but we exploit it to help factor our code into one function.
4740  const bool scrollChildren = !qscrollRect.isValid();
4741 
4742  if (!q->updatesEnabled()) {
4743  // We are told not to update anything on q at this point. So unless
4744  // we are supposed to scroll children, we bail out early:
4745  if (!scrollChildren || q->children().isEmpty())
4746  return;
4747  }
4748 
4749  if (!accelerateScroll) {
4750  if (overlapped) {
4751  QRegion region(validScrollRect);
4752  subtractOpaqueSiblings(region);
4753  update_sys(region);
4754  }else {
4755  update_sys(qscrollRect);
4756  }
4757  }
4758 
4759 #ifdef QT_MAC_USE_COCOA
4761 #else
4762  Q_UNUSED(isAlien);
4763  // We're not sure what the following call is supposed to achive
4764  // but until we see what it breaks, we don't bring it into the
4765  // Cocoa port:
4767 #endif
4768 
4769  // First move all native children. Alien children will indirectly be
4770  // moved when the parent is scrolled. All directly or indirectly moved
4771  // children will receive a move event before the function call returns.
4772  QWidgetList movedChildren;
4773  const QPoint scrollDelta(dx, dy);
4774  if (scrollChildren) {
4775  QObjectList children = q->children();
4776 
4777  for (int i=0; i<children.size(); i++) {
4778  QObject *obj = children.at(i);
4779  if (QWidget *w = qobject_cast<QWidget*>(obj)) {
4780  if (!w->isWindow()) {
4781  w->data->crect = QRect(w->pos() + scrollDelta, w->size());
4782 #ifndef QT_MAC_USE_COCOA
4784  HIRect bounds = CGRectMake(w->data->crect.x(), w->data->crect.y(),
4785  w->data->crect.width(), w->data->crect.height());
4786  HIViewRef hiview = qt_mac_nativeview_for(w);
4787  const bool opaque = q->testAttribute(Qt::WA_OpaquePaintEvent);
4788 
4789  if (opaque)
4790  HIViewSetDrawingEnabled(hiview, false);
4791  HIViewSetFrame(hiview, &bounds);
4792  if (opaque)
4793  HIViewSetDrawingEnabled(hiview, true);
4794  }
4795 #else
4796  if (NSView *view = qt_mac_nativeview_for(w)) {
4797  // INVARIANT: w is not alien
4798  [view setFrame:NSMakeRect(
4799  w->data->crect.x(), w->data->crect.y(),
4800  w->data->crect.width(), w->data->crect.height())];
4801  }
4802 #endif
4803  movedChildren.append(w);
4804  }
4805  }
4806  }
4807  }
4808 
4809  if (q->testAttribute(Qt::WA_WState_Created) && q->isVisible()) {
4810  // Scroll q itself according to the qscrollRect, and
4811  // call update on any exposed areas so that they get redrawn:
4812 
4813 #ifndef QT_MAC_USE_COCOA
4814  OSViewRef view = qt_mac_nativeview_for(q);
4815  HIRect scrollrect = CGRectMake(qscrollRect.x(), qscrollRect.y(), qscrollRect.width(), qscrollRect.height());
4816  OSStatus err = _HIViewScrollRectWithOptions(view, qscrollRect.isValid() ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid);
4817  if (err) {
4818  // The only parameter that can go wrong, is the rect.
4819  qWarning("QWidget::scroll: Your rectangle was too big for the widget, clipping rect");
4820  scrollrect = CGRectMake(qMax(qscrollRect.x(), 0), qMax(qscrollRect.y(), 0),
4821  qMin(qscrollRect.width(), q->width()), qMin(qscrollRect.height(), q->height()));
4822  _HIViewScrollRectWithOptions(view, qscrollRect.isValid() ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid);
4823  }
4824 #else
4825 
4826  QWidget *nativeWidget = isAlien ? q->nativeParentWidget() : q;
4827  if (!nativeWidget)
4828  return;
4829  OSViewRef view = qt_mac_nativeview_for(nativeWidget);
4830  if (!view)
4831  return;
4832 
4833  // Calculate the rectangles that needs to be redrawn
4834  // after the scroll. This will be source rect minus destination rect:
4835  QRect deltaXRect;
4836  if (dx != 0) {
4837  deltaXRect.setY(validScrollRect.y());
4838  deltaXRect.setHeight(validScrollRect.height());
4839  if (dx > 0) {
4840  deltaXRect.setX(validScrollRect.x());
4841  deltaXRect.setWidth(dx);
4842  } else {
4843  deltaXRect.setX(validScrollRect.x() + validScrollRect.width() + dx);
4844  deltaXRect.setWidth(-dx);
4845  }
4846  }
4847 
4848  QRect deltaYRect;
4849  if (dy != 0) {
4850  deltaYRect.setX(validScrollRect.x());
4851  deltaYRect.setWidth(validScrollRect.width());
4852  if (dy > 0) {
4853  deltaYRect.setY(validScrollRect.y());
4854  deltaYRect.setHeight(dy);
4855  } else {
4856  deltaYRect.setY(validScrollRect.y() + validScrollRect.height() + dy);
4857  deltaYRect.setHeight(-dy);
4858  }
4859  }
4860 
4861  if (isAlien) {
4862  // Adjust the scroll rect to the location as seen from the native parent:
4863  QPoint scrollTopLeftInsideNative = nativeWidget->mapFromGlobal(q->mapToGlobal(validScrollRect.topLeft()));
4864  validScrollRect.moveTo(scrollTopLeftInsideNative);
4865  }
4866 
4867  // Make the pixel copy rect within the validScrollRect bounds:
4868  NSRect nsscrollRect = NSMakeRect(
4869  validScrollRect.x() + (dx < 0 ? -dx : 0),
4870  validScrollRect.y() + (dy < 0 ? -dy : 0),
4871  validScrollRect.width() + (dx > 0 ? -dx : 0),
4872  validScrollRect.height() + (dy > 0 ? -dy : 0));
4873 
4874  NSSize deltaSize = NSMakeSize(dx, dy);
4875  [view scrollRect:nsscrollRect by:deltaSize];
4876 
4877  // Some areas inside the scroll rect might have been marked as dirty from before, which
4878  // means that they are scheduled to be redrawn. But as we now scroll, those dirty rects
4879  // should also move along to ensure that q receives repaints on the correct places.
4880  // Since some of the dirty rects might lay outside, or only intersect with, the scroll
4881  // rect, the old calls to setNeedsDisplay still makes sense.
4882  // NB: Using [view translateRectsNeedingDisplayInRect:nsscrollRect by:deltaSize] have
4883  // so far not been proven fruitful to solve this problem.
4884  const QVector<QRect> &dirtyRectsToScroll = dirtyOnWidget.rects();
4885  for (int i=0; i<dirtyRectsToScroll.size(); ++i) {
4886  QRect qdirtyRect = dirtyRectsToScroll[i];
4887  qdirtyRect.translate(dx, dy);
4888  update_sys(qdirtyRect);
4889  }
4890 
4891  // Update newly exposed areas. This will generate new dirty areas on
4892  // q, and therefore, we do it after updating the old dirty rects above:
4893  if (dx != 0)
4894  update_sys(deltaXRect);
4895  if (dy != 0)
4896  update_sys(deltaYRect);
4897 
4898 #endif // QT_MAC_USE_COCOA
4899  }
4900 
4901  for (int i=0; i<movedChildren.size(); i++) {
4902  QWidget *w = movedChildren.at(i);
4903  QMoveEvent e(w->pos(), w->pos() - scrollDelta);
4904  QApplication::sendEvent(w, &e);
4905  }
4906 }
4907 
4909 {
4910  switch(m) {
4911  case PdmHeightMM:
4912  return qRound(metric(PdmHeight) * 25.4 / qreal(metric(PdmDpiY)));
4913  case PdmWidthMM:
4914  return qRound(metric(PdmWidth) * 25.4 / qreal(metric(PdmDpiX)));
4915  case PdmHeight:
4916  case PdmWidth:
4917 #ifndef QT_MAC_USE_COCOA
4918  { HIRect rect;
4919  HIViewGetFrame(qt_mac_nativeview_for(this), &rect);
4920  if(m == PdmWidth)
4921  return (int)rect.size.width;
4922  return (int)rect.size.height; }
4923 #else
4924  if (m == PdmWidth)
4925  return data->crect.width();
4926  else
4927  return data->crect.height();
4928 #endif
4929  case PdmDepth:
4930  return 32;
4931  case PdmNumColors:
4932  return INT_MAX;
4933  case PdmDpiX:
4934  case PdmPhysicalDpiX: {
4935  Q_D(const QWidget);
4936  if (d->extra && d->extra->customDpiX)
4937  return d->extra->customDpiX;
4938  else if (d->parent)
4939  return static_cast<QWidget *>(d->parent)->metric(m);
4940  extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
4941  return int(qt_mac_defaultDpi_x()); }
4942  case PdmDpiY:
4943  case PdmPhysicalDpiY: {
4944  Q_D(const QWidget);
4945  if (d->extra && d->extra->customDpiY)
4946  return d->extra->customDpiY;
4947  else if (d->parent)
4948  return static_cast<QWidget *>(d->parent)->metric(m);
4949  extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
4950  return int(qt_mac_defaultDpi_y()); }
4951  default: //leave this so the compiler complains when new ones are added
4952  qWarning("QWidget::metric: Unhandled parameter %d", m);
4953  return QPaintDevice::metric(m);
4954  }
4955  return 0;
4956 }
4957 
4959 {
4960 #ifdef QT_MAC_USE_COCOA
4961  extra->imageMask = 0;
4962 #endif
4963 }
4964 
4966 {
4967 #ifdef QT_MAC_USE_COCOA
4968  if (extra->imageMask)
4969  CFRelease(extra->imageMask);
4970 #endif
4971 }
4972 
4974 {
4975  extra->topextra->resizer = 0;
4976  extra->topextra->isSetGeometry = 0;
4977  extra->topextra->isMove = 0;
4978  extra->topextra->wattr = 0;
4979  extra->topextra->wclass = 0;
4980  extra->topextra->group = 0;
4981  extra->topextra->windowIcon = 0;
4982  extra->topextra->savedWindowAttributesFromMaximized = 0;
4983 }
4984 
4986 {
4987 #ifndef QT_MAC_USE_COCOA
4988  if (extra->topextra->group) {
4990  extra->topextra->group = 0;
4991  }
4992  if (extra->topextra->windowIcon) {
4993  ReleaseIconRef(extra->topextra->windowIcon);
4994  extra->topextra->windowIcon = 0;
4995  }
4996 #endif
4997 }
4998 
5000 {
5001  Q_Q(QWidget);
5002 
5003  QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
5004 
5005  that->data.fstrut_dirty = false;
5006  QTLWExtra *top = that->topData();
5007 
5008 #if QT_MAC_USE_COCOA
5009  // 1 Get the window frame
5010  OSWindowRef oswnd = qt_mac_window_for(q);
5011  NSRect frameW = [oswnd frame];
5012  // 2 Get the content frame - so now
5013  NSRect frameC = [oswnd contentRectForFrameRect:frameW];
5014  top->frameStrut.setCoords(frameC.origin.x - frameW.origin.x,
5015  (frameW.origin.y + frameW.size.height) - (frameC.origin.y + frameC.size.height),
5016  (frameW.origin.x + frameW.size.width) - (frameC.origin.x + frameC.size.width),
5017  frameC.origin.y - frameW.origin.y);
5018 #else
5019  Rect window_r;
5020  GetWindowStructureWidths(qt_mac_window_for(q), &window_r);
5021  top->frameStrut.setCoords(window_r.left, window_r.top, window_r.right, window_r.bottom);
5022 #endif
5023 }
5024 
5026 {
5027  Q_Q(QWidget);
5028  if (!q->testAttribute(Qt::WA_WState_Created))
5029  return;
5030 #ifndef QT_MAC_USE_COCOA
5031  SetControlDragTrackingEnabled(qt_mac_nativeview_for(q), on);
5032 #else
5033  NSWindow *win = qt_mac_window_for(q);
5034  if (on) {
5035  if ([win isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaWindow) class]])
5036  [static_cast<QT_MANGLE_NAMESPACE(QCocoaWindow) *>(win) registerDragTypes];
5037  else if ([win isKindOfClass:[QT_MANGLE_NAMESPACE(QCocoaPanel) class]])
5038  [static_cast<QT_MANGLE_NAMESPACE(QCocoaPanel) *>(win) registerDragTypes];
5039  }
5040 #endif
5041 }
5042 
5043 void QWidgetPrivate::registerTouchWindow(bool enable)
5044 {
5045  Q_UNUSED(enable);
5046 #ifdef QT_MAC_USE_COCOA
5047 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
5049  return;
5050 
5051  Q_Q(QWidget);
5052  if (enable == touchEventsEnabled)
5053  return;
5054 
5055  QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_effectiveview_for(q));
5056  if (!view)
5057  return;
5058 
5059  if (enable) {
5060  ++view->alienTouchCount;
5061  if (view->alienTouchCount == 1) {
5062  touchEventsEnabled = true;
5063  [view setAcceptsTouchEvents:YES];
5064  }
5065  } else {
5066  --view->alienTouchCount;
5067  if (view->alienTouchCount == 0) {
5068  touchEventsEnabled = false;
5069  [view setAcceptsTouchEvents:NO];
5070  }
5071  }
5072 #endif
5073 #endif
5074 }
5075 
5077 {
5078  Q_UNUSED(region);
5079  Q_Q(QWidget);
5080 
5081 #ifndef QT_MAC_USE_COCOA
5082  if (q->isWindow())
5083  ReshapeCustomWindow(qt_mac_window_for(q));
5084  else
5085  HIViewReshapeStructure(qt_mac_nativeview_for(q));
5086 #else
5087  if (!q->internalWinId())
5088  return;
5089 
5090  if (extra->mask.isEmpty()) {
5091  extra->maskBits = QImage();
5092  finishCocoaMaskSetup();
5093  } else {
5094  syncCocoaMask();
5095  }
5096 
5097  topLevelAt_cache = 0;
5098 #endif
5099 }
5100 
5102 {
5103  Q_Q(QWidget);
5104 
5105  if (!q->isWindow())
5106  return;
5107 
5108  level = qBound(0.0, level, 1.0);
5109  topData()->opacity = (uchar)(level * 255);
5110  if (!q->testAttribute(Qt::WA_WState_Created))
5111  return;
5112 
5113  OSWindowRef oswindow = qt_mac_window_for(q);
5114 #if QT_MAC_USE_COCOA
5115  [oswindow setAlphaValue:level];
5116 #else
5117  SetWindowAlpha(oswindow, level);
5118 #endif
5119 }
5120 
5121 #ifdef QT_MAC_USE_COCOA
5122 void QWidgetPrivate::syncCocoaMask()
5123 {
5124  Q_Q(QWidget);
5125  if (!q->testAttribute(Qt::WA_WState_Created) || !extra)
5126  return;
5127 
5128  if (extra->hasMask) {
5129  if(extra->maskBits.size() != q->size()) {
5130  extra->maskBits = QImage(q->size(), QImage::Format_Mono);
5131  }
5132  extra->maskBits.fill(QColor(Qt::color1).rgba());
5133  extra->maskBits.setNumColors(2);
5134  extra->maskBits.setColor(0, QColor(Qt::color0).rgba());
5135  extra->maskBits.setColor(1, QColor(Qt::color1).rgba());
5136  QPainter painter(&extra->maskBits);
5137  painter.setBrush(Qt::color1);
5138  painter.setPen(Qt::NoPen);
5139  painter.drawRects(extra->mask.rects());
5140  painter.end();
5141  finishCocoaMaskSetup();
5142  }
5143 }
5144 
5145 void QWidgetPrivate::finishCocoaMaskSetup()
5146 {
5147  Q_Q(QWidget);
5148 
5149  if (!q->testAttribute(Qt::WA_WState_Created) || !extra)
5150  return;
5151 
5152  // Technically this is too late to release, because the data behind the image
5153  // has already been released. But it's more tidy to do it here.
5154  // If you are seeing a crash, consider doing a CFRelease before changing extra->maskBits.
5155  if (extra->imageMask) {
5156  CFRelease(extra->imageMask);
5157  extra->imageMask = 0;
5158  }
5159 
5160  if (!extra->maskBits.isNull()) {
5161  QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(0,
5162  extra->maskBits.bits(),
5163  extra->maskBits.numBytes(),
5164  0); // shouldn't need to release.
5165  CGFloat decode[2] = {1, 0};
5166  extra->imageMask = CGImageMaskCreate(extra->maskBits.width(), extra->maskBits.height(),
5167  1, 1, extra->maskBits.bytesPerLine(), dataProvider,
5168  decode, false);
5169  }
5170  if (q->isWindow()) {
5171  NSWindow *window = qt_mac_window_for(q);
5172  [window setOpaque:(extra->imageMask == 0)];
5173  [window invalidateShadow];
5174  }
5175  macSetNeedsDisplay(QRegion());
5176 }
5177 #endif
5178 
5180 {
5181  inline QPaintEngineCleanupHandler() : engine(0) {}
5182  inline ~QPaintEngineCleanupHandler() { delete engine; }
5184 };
5185 
5187 
5188 QPaintEngine *QWidget::paintEngine() const
5189 {
5190  QPaintEngine *&pe = engineHandler()->engine;
5191  if (!pe)
5192  pe = new QCoreGraphicsPaintEngine();
5193  if (pe->isActive()) {
5194  QPaintEngine *engine = new QCoreGraphicsPaintEngine();
5195  engine->setAutoDestruct(true);
5196  return engine;
5197  }
5198  return pe;
5199 }
5200 
5202 {
5203  Q_Q(QWidget);
5204  if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow())
5205  return;
5206  const QWidget * const windowParent = q->window()->parentWidget();
5207  const QWidget * const primaryWindow = windowParent ? windowParent->window() : 0;
5208  OSWindowRef windowRef = qt_mac_window_for(q);
5209 
5210 #ifdef QT_MAC_USE_COCOA
5212  bool alreadySheet = [windowRef styleMask] & NSDocModalWindowMask;
5213 
5214  if (windowParent && q->windowModality() == Qt::WindowModal){
5215  // INVARIANT: Window should be window-modal (which implies a sheet).
5216  if (!alreadySheet) {
5217  // NB: the following call will call setModal_sys recursivly:
5218  recreateMacWindow();
5219  windowRef = qt_mac_window_for(q);
5220  }
5221  if ([windowRef isKindOfClass:[NSPanel class]]){
5222  // If the primary window of the sheet parent is a child of a modal dialog,
5223  // the sheet parent should not be modally shaddowed.
5224  // This goes for the sheet as well:
5225  OSWindowRef ref = primaryWindow ? qt_mac_window_for(primaryWindow) : 0;
5226  bool isDialog = ref ? [ref isKindOfClass:[NSPanel class]] : false;
5227  bool worksWhenModal = isDialog ? [static_cast<NSPanel *>(ref) worksWhenModal] : false;
5228  if (worksWhenModal)
5229  [static_cast<NSPanel *>(windowRef) setWorksWhenModal:YES];
5230  }
5231  } else {
5232  // INVARIANT: Window shold _not_ be window-modal (and as such, not a sheet).
5233  if (alreadySheet){
5234  // NB: the following call will call setModal_sys recursivly:
5235  recreateMacWindow();
5236  windowRef = qt_mac_window_for(q);
5237  }
5238  if (q->windowModality() == Qt::NonModal
5239  && primaryWindow && primaryWindow->windowModality() == Qt::ApplicationModal) {
5240  // INVARIANT: Our window has a parent that is application modal.
5241  // This means that q is supposed to be on top of this window and
5242  // not be modally shaddowed:
5243  if ([windowRef isKindOfClass:[NSPanel class]])
5244  [static_cast<NSPanel *>(windowRef) setWorksWhenModal:YES];
5245  }
5246  }
5247 
5248 #else
5249  const bool primaryWindowModal = primaryWindow ? primaryWindow->testAttribute(Qt::WA_ShowModal) : false;
5250  const bool modal = q->testAttribute(Qt::WA_ShowModal);
5251 
5252  WindowClass old_wclass;
5253  GetWindowClass(windowRef, &old_wclass);
5254 
5255  if (modal || primaryWindowModal) {
5256  if (q->windowModality() == Qt::WindowModal
5257  || (primaryWindow && primaryWindow->windowModality() == Qt::WindowModal)){
5258  // Window should be window-modal (which implies a sheet).
5259  if (old_wclass != kSheetWindowClass){
5260  // We cannot convert a created window to a sheet.
5261  // So we recreate the window:
5262  recreateMacWindow();
5263  return;
5264  }
5265  } else {
5266  // Window should be application-modal (which implies NOT using a sheet).
5267  if (old_wclass == kSheetWindowClass){
5268  // We cannot convert a sheet to a window.
5269  // So we recreate the window:
5270  recreateMacWindow();
5271  return;
5272  } else if (!(q->data->window_flags & Qt::CustomizeWindowHint)) {
5273  if (old_wclass == kDocumentWindowClass || old_wclass == kFloatingWindowClass || old_wclass == kUtilityWindowClass){
5274  // Only change the class to kMovableModalWindowClass if the no explicit jewels
5275  // are set (kMovableModalWindowClass can't contain them), and the current window class
5276  // can be converted to modal (according to carbon doc). Mind the order of
5277  // HIWindowChangeClass and ChangeWindowAttributes.
5278  WindowGroupRef group = GetWindowGroup(windowRef);
5279  HIWindowChangeClass(windowRef, kMovableModalWindowClass);
5280  quint32 tmpWattr = kWindowCloseBoxAttribute | kWindowHorizontalZoomAttribute;
5281  ChangeWindowAttributes(windowRef, tmpWattr, kWindowNoAttributes);
5282  ChangeWindowAttributes(windowRef, kWindowNoAttributes, tmpWattr);
5283  // If the window belongs to a qt-created group, set that group once more:
5285  || q->windowType() == Qt::Popup
5286  || q->windowType() == Qt::ToolTip)
5287  SetWindowGroup(windowRef, group);
5288  }
5289  // Popups are usually handled "special" and are never modal.
5290  Qt::WindowType winType = q->windowType();
5291  if (winType != Qt::Popup && winType != Qt::ToolTip)
5292  SetWindowModality(windowRef, kWindowModalityAppModal, 0);
5293  }
5294  }
5295  } else if (windowRef) {
5296  if (old_wclass == kSheetWindowClass){
5297  // Converting a sheet to a window is complex. It's easier to recreate:
5298  recreateMacWindow();
5299  return;
5300  }
5301 
5302  SetWindowModality(windowRef, kWindowModalityNone, 0);
5303  if (!(q->data->window_flags & Qt::CustomizeWindowHint)) {
5304  if (q->window()->d_func()->topData()->wattr |= kWindowCloseBoxAttribute)
5305  ChangeWindowAttributes(windowRef, kWindowCloseBoxAttribute, kWindowNoAttributes);
5306  if (q->window()->d_func()->topData()->wattr |= kWindowHorizontalZoomAttribute)
5307  ChangeWindowAttributes(windowRef, kWindowHorizontalZoomAttribute, kWindowNoAttributes);
5308  if (q->window()->d_func()->topData()->wattr |= kWindowCollapseBoxAttribute)
5309  ChangeWindowAttributes(windowRef, kWindowCollapseBoxAttribute, kWindowNoAttributes);
5310  }
5311 
5312  WindowClass newClass = q->window()->d_func()->topData()->wclass;
5313  if (old_wclass != newClass && newClass != 0){
5314  WindowGroupRef group = GetWindowGroup(windowRef);
5315  HIWindowChangeClass(windowRef, newClass);
5316  // If the window belongs to a qt-created group, set that group once more:
5318  || q->windowType() == Qt::Popup
5319  || q->windowType() == Qt::ToolTip)
5320  SetWindowGroup(windowRef, group);
5321  }
5322  }
5323 
5324  // Make sure that HIWindowChangeClass didn't remove drag support
5325  // or reset the opaque size grip setting:
5326  SetAutomaticControlDragTrackingEnabledForWindow(windowRef, true);
5327  macUpdateOpaqueSizeGrip();
5328 #endif
5329 }
5330 
5331 void QWidgetPrivate::macUpdateHideOnSuspend()
5332 {
5333  Q_Q(QWidget);
5334  if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow() || q->windowType() != Qt::Tool)
5335  return;
5336 #ifndef QT_MAC_USE_COCOA
5337  if(q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
5338  ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowHideOnSuspendAttribute);
5339  else
5340  ChangeWindowAttributes(qt_mac_window_for(q), kWindowHideOnSuspendAttribute, 0);
5341 #else
5342  if(q->testAttribute(Qt::WA_MacAlwaysShowToolWindow))
5343  [qt_mac_window_for(q) setHidesOnDeactivate:NO];
5344  else
5345  [qt_mac_window_for(q) setHidesOnDeactivate:YES];
5346 #endif
5347 }
5348 
5349 void QWidgetPrivate::macUpdateOpaqueSizeGrip()
5350 {
5351  Q_Q(QWidget);
5352 
5353  if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow())
5354  return;
5355 
5356 #ifndef QT_MAC_USE_COCOA // Growbox is always transparent on Cocoa. Can emulate with setting a QSizeGrip
5357  HIViewRef growBox;
5358  HIViewFindByID(HIViewGetRoot(qt_mac_window_for(q)), kHIViewWindowGrowBoxID, &growBox);
5359  if (!growBox)
5360  return;
5361  HIGrowBoxViewSetTransparent(growBox, !q->testAttribute(Qt::WA_MacOpaqueSizeGrip));
5362 #endif
5363 }
5364 
5365 void QWidgetPrivate::macUpdateSizeAttribute()
5366 {
5367  Q_Q(QWidget);
5369  QApplication::sendEvent(q, &event);
5370  for (int i = 0; i < children.size(); ++i) {
5371  QWidget *w = qobject_cast<QWidget *>(children.at(i));
5372  if (w && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
5373  && !q->testAttribute(Qt::WA_MacMiniSize) // no attribute set? inherit from parent
5376  w->d_func()->macUpdateSizeAttribute();
5377  }
5378  resolveFont();
5379 }
5380 
5381 void QWidgetPrivate::macUpdateIgnoreMouseEvents()
5382 {
5383 #ifndef QT_MAC_USE_COCOA // This is handled inside the mouse handler on Cocoa.
5384  Q_Q(QWidget);
5385  if (!q->testAttribute(Qt::WA_WState_Created))
5386  return;
5387 
5388  if(q->isWindow())
5389  {
5390  if(q->testAttribute(Qt::WA_TransparentForMouseEvents))
5391  ChangeWindowAttributes(qt_mac_window_for(q), kWindowIgnoreClicksAttribute, 0);
5392  else
5393  ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowIgnoreClicksAttribute);
5394  ReshapeCustomWindow(qt_mac_window_for(q));
5395  } else {
5396 #ifndef kHIViewFeatureIgnoresClicks
5397 #define kHIViewFeatureIgnoresClicks kHIViewIgnoresClicks
5398 #endif
5399  if(q->testAttribute(Qt::WA_TransparentForMouseEvents))
5400  HIViewChangeFeatures(qt_mac_nativeview_for(q), kHIViewFeatureIgnoresClicks, 0);
5401  else
5402  HIViewChangeFeatures(qt_mac_nativeview_for(q), 0, kHIViewFeatureIgnoresClicks);
5403  HIViewReshapeStructure(qt_mac_nativeview_for(q));
5404  }
5405 #endif
5406 }
5407 
5408 void QWidgetPrivate::macUpdateMetalAttribute()
5409 {
5410  Q_Q(QWidget);
5411  bool realWindow = isRealWindow();
5412  if (!q->testAttribute(Qt::WA_WState_Created) || !realWindow)
5413  return;
5414 
5415  if (realWindow) {
5416 #if QT_MAC_USE_COCOA
5417  // Cocoa doesn't let us change the style mask once it's been changed
5418  // So, that means we need to recreate the window.
5419  OSWindowRef cocoaWindow = qt_mac_window_for(q);
5420  if ([cocoaWindow styleMask] & NSTexturedBackgroundWindowMask)
5421  return;
5422  recreateMacWindow();
5423 #else
5424  QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q));
5425  if (q->testAttribute(Qt::WA_MacBrushedMetal)) {
5426  if (layout)
5427  layout->updateHIToolBarStatus();
5428  ChangeWindowAttributes(qt_mac_window_for(q), kWindowMetalAttribute, 0);
5429  ChangeWindowAttributes(qt_mac_window_for(q), kWindowMetalNoContentSeparatorAttribute, 0);
5430  } else {
5431  ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowMetalNoContentSeparatorAttribute);
5432  ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowMetalAttribute);
5433  if (layout)
5434  layout->updateHIToolBarStatus();
5435  }
5436 #endif
5437  }
5438 }
5439 
5440 void QWidgetPrivate::setEnabled_helper_sys(bool enable)
5441 {
5442 #ifdef QT_MAC_USE_COCOA
5443  Q_Q(QWidget);
5444  NSView *view = qt_mac_nativeview_for(q);
5445  if ([view isKindOfClass:[NSControl class]])
5446  [static_cast<NSControl *>(view) setEnabled:enable];
5447 #else
5448  Q_UNUSED(enable);
5449 #endif
5450 }
5451 
QSize maximumSize() const
Reimplemented Function
static const EventHandlerUPP make_widget_eventUPP()
T qobject_cast(QObject *object)
Definition: qobject.h:375
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
virtual bool macEvent(EventHandlerCallRef, EventRef)
This special event handler can be reimplemented in a subclass to receive native Macintosh events...
Definition: qwidget.cpp:9918
static void jump(QtMsgType t, const char *m)
QPalette palette
the widget&#39;s palette
Definition: qwidget.h:180
void setParent_sys(QWidget *parent, Qt::WindowFlags)
const struct __CFString * CFStringRef
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
Q_GUI_EXPORT OSWindowRef qt_mac_window_for(OSViewRef view)
Definition: qwidget_mac.mm:453
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QWidget * focusWidget() const
Returns the last child of this widget that setFocus had been called on.
Definition: qwidget.cpp:6863
unsigned long WId
Definition: qwindowdefs.h:119
static void qt_mac_set_fullscreen_mode(bool b)
Definition: qwidget_mac.mm:406
static void qt_mac_destructWindow(OSWindowRef window)
Definition: qwidget_mac.mm:253
void grabMouse()
Grabs the mouse input.
void setHeight(int h)
Sets the height of the rectangle to the given height.
Definition: qrect.h:445
void setWindowIcon_sys(bool forceReset=false)
virtual void interrupt()=0
Interrupts event dispatching; i.
int type
Definition: qmetatype.cpp:239
static EventTypeSpec widget_events[]
IconRef qt_mac_create_iconref(const QPixmap &)
double qreal
Definition: qglobal.h:1193
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition: qcursor.h:89
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const QColor & color() const
Returns the brush color.
Definition: qbrush.h:183
int metric(PaintDeviceMetric) const
Internal implementation of the virtual QPaintDevice::metric() function.
static void qt_mac_release_window_group(WindowGroupRef group)
Definition: qwidget_mac.mm:530
QWidget * mac_mouse_grabber
Definition: qwidget_mac.mm:156
EventRef event
QPointer< QWidget > widget
QRect frameStrut
Definition: qwidget_p.h:180
Qt::WindowStates windowState() const
Returns the current window state.
Definition: qwidget.cpp:3086
static void cleanup_win_eventUPP()
Definition: qwidget_mac.mm:841
void setWindowState(Qt::WindowStates state)
Sets the window state to windowState.
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
bool isActiveWindow
whether this widget&#39;s window is the active window
Definition: qwidget.h:186
QRect crect
Definition: qwidget.h:131
QPoint mapTo(QWidget *, const QPoint &) const
Translates the widget coordinate pos to the coordinate system of parent.
Definition: qwidget.cpp:4409
void setWindowIconText_helper(const QString &cap)
Definition: qwidget.cpp:6292
int flipYCoordinate(int y)
Qt::HANDLE hd
Definition: qwidget_p.h:754
#define it(className, varName)
void qAddPostRoutine(QtCleanUpFunction p)
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
WId effectiveWinId() const
Returns the effective window system identifier of the widget, i.
Definition: qwidget.cpp:2654
struct OpaqueWindowPtr * WindowRef
QLayout * layout
Definition: qwidget_p.h:704
bool isVisible() const
Definition: qwidget.h:1005
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
QDrag * object
Definition: qdnd_p.h:238
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
bool paintOnScreen() const
Definition: qwidget.cpp:2255
bool qt_event_remove_activate()
const UInt32 kWidgetCreatorQt
Definition: qwidget_mac.mm:148
void qt_mac_unregister_widget()
static OSWindowRef qt_mac_create_window(QWidget *, WindowClass wclass, WindowAttributes wattr, const QRect &crect)
Definition: qwidget_mac.mm:778
static void adjustFlags(Qt::WindowFlags &flags, QWidget *w=0)
Definition: qwidget.cpp:1242
static bool delayScroll(QWidgetPrivate *target, int dx, int dy, const QRect &scrollRect)
QPointer< QWidget > topLevelAt_cache
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
void setWindowTitle_sys(const QString &cap)
void moveRect(const QRect &, int dx, int dy)
uint window_state
Definition: qwidget.h:120
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QPointer< QWidget > qt_button_down
static const EventHandlerUPP make_win_eventUPP()
Definition: qwidget_mac.mm:846
#define kHIViewFeatureIgnoresClicks
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
Definition: qpixmap.h:132
QRect translated(int dx, int dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:328
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
The QList::const_iterator class provides an STL-style const iterator for QList and QQueue...
Definition: qlist.h:228
void deleteTLSysExtra()
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
struct CGImage * CGImageRef
bool exists() const
Returns true if the file exists; otherwise returns false.
Definition: qfileinfo.cpp:675
static QApplicationPrivate * instance()
void * qt_mac_create_nsimage(const QPixmap &pm)
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *window)
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt)
void moveTo(int x, int t)
Moves the rectangle, leaving the top-left corner at the given position (x, y).
Definition: qrect.h:334
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qwidget.h:1017
void show_sys()
Platform-specific part of QWidget::show().
QPointF flipPoint(const NSPoint &p)
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
void setY(int y)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:285
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
The QString class provides a Unicode character string.
Definition: qstring.h:83
bool hasFocus() const
Definition: qwidget.cpp:6583
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
void update(const QRectF &rect=QRectF())
Schedules a redraw of the area covered by rect in this item.
WindowType
Definition: qnamespace.h:270
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
QTLWExtra * maybeTopData() const
Definition: qwidget_p.h:1010
#define Q_D(Class)
Definition: qglobal.h:2482
float qt_mac_defaultDpi_y()
QRect normalGeometry
the geometry of the widget as it will appear when shown as a normal (not maximized or full screen) to...
Definition: qwidget.h:160
static QSize closestAcceptableSize(const QWidget *w, const QSize &s)
Returns a size that satisfies all size constraints on widget, including heightForWidth() and that is ...
Definition: qlayout.cpp:1586
void scrollChildren(int dx, int dy)
Definition: qwidget.cpp:421
QObjectList children
Definition: qobject.h:93
QThreadData * threadData
Definition: qobject_p.h:195
void setCursor_sys(const QCursor &cursor)
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
void setAutoDestruct(bool autoDestr)
Definition: qpaintengine.h:249
NSToolbar * toolbar
#define HIViewInstallEventHandler(target, handler, numTypes, list, userData, outHandlerRef)
bool autoFillBackground
whether the widget background is filled automatically
Definition: qwidget.h:218
qint32 minw
Definition: qwidget_p.h:264
QWidget * mac_keyboard_grabber
Definition: qwidget_mac.mm:157
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void registerDropSite(bool)
bool paintingActive() const
Definition: qpaintdevice.h:170
uint embedded
Definition: qwidget_p.h:190
static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRect &rect)
Definition: qwidget_mac.mm:592
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
OSStatus _HIViewScrollRectWithOptions(HIViewRef, const HIRect *, CGFloat, CGFloat, OptionBits) __attribute__((weak))
#define WRECT_MAX
Definition: qwidget_mac.mm:121
bool qt_nograb()
void macSendToolbarChangeEvent(QWidget *widget)
#define Q_Q(Class)
Definition: qglobal.h:2483
uint window_modality
Definition: qwidget.h:128
void setWindowFilePath_helper(const QString &filePath)
Definition: qwidget.cpp:6461
static void qt_mac_set_window_group_to_stays_on_top(OSWindowRef window, Qt::WindowType type)
Definition: qwidget_mac.mm:564
NSComparisonResult compareViews2StackUnder(id view1, id view2, void *context)
static void cleanup_widget_eventUPP()
QWidgetData data
Definition: qwidget_p.h:755
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
QGraphicsProxyWidget * proxyWidget
Definition: qwidget_p.h:251
void deactivateWidgetCleanup()
Definition: qwidget.cpp:2496
Q_CORE_EXPORT void qDebug(const char *,...)
static QWidget * widgetAt(const QPoint &p)
Returns the widget at global screen position point, or 0 if there is no Qt widget there...
static HIObjectClassRef widget_class
unsigned char uchar
Definition: qglobal.h:994
void setParent_helper(QObject *)
Definition: qobject.cpp:1974
NSWindow * window
int width() const
Returns the width.
Definition: qsize.h:126
#define ReleaseWindowGroup(x)
Definition: qwidget_mac.mm:536
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
static void qt_mac_set_window_group_to_tooltip(OSWindowRef window)
Definition: qwidget_mac.mm:573
void create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
void unsetCursor_sys()
void drawRects(const QRectF *rects, int rectCount)
Draws the first rectCount of the given rectangles using the current pen and brush.
Definition: qpainter.cpp:3641
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QWidget * nativeParentWidget() const
Returns the native parent for this widget, i.
Definition: qwidget.cpp:4514
bool isActive() const
Returns true if the paint engine is actively drawing; otherwise returns false.
Definition: qpaintengine.h:154
void qt_mac_set_cursor(const QCursor *, const QPoint &)
The QMoveEvent class contains event parameters for move events.
Definition: qevent.h:334
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
CGImageRef qt_mac_create_cgimage(const QPixmap &, bool)
QPoint bottomRight() const
Returns the position of the rectangle&#39;s bottom-right corner.
Definition: qrect.h:291
void destroy(bool destroyWindow=true, bool destroySubWindows=true)
Frees up window system resources.
bool updatesEnabled
whether updates are enabled
Definition: qwidget.h:190
static bool qt_isGenuineQWidget(OSViewRef ref)
Definition: qwidget_mac.mm:464
#define SF(x)
void releaseMouse()
Releases the mouse grab.
WindowRef OSWindowRef
static EventHandlerUPP mac_win_eventUPP
Definition: qwidget_mac.mm:840
static QWidget * mouseGrabber()
Returns the widget that is currently grabbing the mouse input.
static void setFocusWidget(QWidget *focus, Qt::FocusReason reason)
qint32 maxw
Definition: qwidget_p.h:266
int height
the height of the widget excluding any window frame
Definition: qwidget.h:167
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
Definition: qregion.cpp:4098
#define qApp
void qt_event_request_activate(QWidget *)
QRect frameStrut() const
Definition: qwidget.cpp:12607
Qt::WindowFlags window_flags
Definition: qwidget.h:119
static void qt_mac_destructDrawer(NSDrawer *drawer)
Definition: qwidget_mac.mm:270
const char * name
qint32 maxh
Definition: qwidget_p.h:267
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
void hide_sys()
Platform-specific part of QWidget::hide().
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void setConstraints_sys()
struct OpaqueControlRef * HIViewRef
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition: qicon.cpp:769
static QWidget * find(WId)
Returns a pointer to the widget with window identifer/handle id.
Definition: qwidget.cpp:2517
void setRight(int pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:264
Qt::WindowModality windowModality
which windows are blocked by the modal widget
Definition: qwidget.h:156
QWidgetData * data
Definition: qwidget.h:815
static EventHandlerUPP mac_widget_eventUPP
static bool sendSpontaneousEvent(QObject *receiver, QEvent *event)
bool isNull() const
Returns true if both the x and y coordinates are set to 0, otherwise returns false.
Definition: qpoint.h:125
void updateFrameStrut()
Computes the frame rectangle when needed.
The QResizeEvent class contains event parameters for resize events.
Definition: qevent.h:349
QHash< Qt::WindowFlags, WindowGroupRef > WindowGroupHash
Definition: qwidget_mac.mm:146
Q_CORE_EXPORT void qWarning(const char *,...)
void setSize(const QSize &s)
Sets the size of the rectangle to the given size.
Definition: qrect.h:448
static void clearColorSpace(QWidget *w)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
unsigned int uint
Definition: qglobal.h:996
bool qt_mac_is_macsheet(const QWidget *w)
Definition: qwidget_mac.mm:295
bool qt_mac_sendMacEventToWidget(QWidget *widget, EventRef ref)
Definition: qwidget_mac.mm:448
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
#define S
Definition: qwidget_mac.mm:165
OSViewRef qt_mac_create_widget(QWidget *widget, QWidgetPrivate *widgetPrivate, OSViewRef parent)
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
NSComparisonResult compareViews2Lower(id view1, id view2, void *context)
QSize size
the size of the widget excluding any window frame
Definition: qwidget.h:165
QRect wrect
Definition: qwidget.h:145
void * HANDLE
Definition: qnamespace.h:1671
QTLWExtra * topData() const
Definition: qwidget_p.h:1004
void setCoords(int x1, int y1, int x2, int y2)
Sets the coordinates of the rectangle&#39;s top-left corner to (x1, y1), and the coordinates of its botto...
Definition: qrect.h:416
void qt_mac_send_posted_gl_updates(QWidget *widget)
void setWindowTitle_helper(const QString &cap)
Definition: qwidget.cpp:6285
static void qt_mac_release_stays_on_top_group(WindowGroupRef group)
Definition: qwidget_mac.mm:518
void show()
Shows the widget and its child widgets.
static OSWindowRef qt_root_win
Definition: qwidget_mac.mm:155
The QShowEvent class provides an event that is sent when a widget is shown.
Definition: qevent.h:380
signed long OSStatus
Q_GUI_EXPORT OSViewRef qt_mac_get_contentview_for(OSWindowRef w)
Definition: qwidget_mac.mm:431
The QWidgetItem class is a layout item that represents a widget.
Definition: qlayoutitem.h:122
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
void deleteSysExtra()
#define QT_CATCH(A)
Definition: qglobal.h:1537
void setSystemClip(const QRegion &baseClip)
Sets the system clip for this engine.
struct OpaqueRgnHandle * RgnHandle
void setX(int x)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:282
QRegion mask() const
Returns the mask currently set on a widget.
Definition: qwidget.cpp:10058
void qt_mac_updateParentUnderAlienWidget(QWidget *alienWidget)
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
bool qt_mac_is_macdrawer(const QWidget *w)
Definition: qwidget_mac.mm:306
The QWindowSurface class provides the drawing area for top-level windows.
struct OpaqueEventRef * EventRef
void hide()
Hides the widget.
Definition: qwidget.h:501
void moveTopLeft(const QPoint &p)
Moves the rectangle, leaving the top-left corner at the given position.
Definition: qrect.h:368
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
static QWidget * parentWidget(const QWidget *w)
bool isMaximized() const
Definition: qwidget.cpp:3074
void invalidateBuffer(const QRegion &)
Invalidates the rgn (in widget&#39;s coordinates) of the backing store, i.e.
Q_GUI_EXPORT OSViewRef qt_mac_nativeview_for(const QWidget *w)
Definition: qwidget_mac.mm:419
static QDesktopWidget * desktop()
Returns the desktop widget (also called the root window).
static QDragManager * self()
Definition: qdnd.cpp:163
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QSize minimumSize() const
Reimplemented Function
QPoint center() const
Returns the center point of the rectangle.
Definition: qrect.h:300
struct CGRect CGRect
bool unifiedTitleAndToolBarOnMac
whether the window uses the unified title and toolbar look on Mac OS X
Definition: qmainwindow.h:83
static QSize qt_mac_desktopSize()
Definition: qwidget_mac.mm:203
DockWidgetArea
Definition: qnamespace.h:1337
void setFocus()
Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its paren...
Definition: qwidget.h:432
static bool tryModalHelper(QWidget *widget, QWidget **rettop=0)
void grabKeyboard()
Grabs the keyboard input.
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
static void qt_mac_update_widget_position(QWidget *q, QRect oldRect, QRect newRect)
QString filePath
Definition: qwidget_p.h:174
QRegion mask
Definition: qwidget_p.h:260
The QWindowStateChangeEvent class provides the window state before a window state change...
Definition: qevent.h:705
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
QTLWExtra * topextra
Definition: qwidget_p.h:249
QWindowSurface * createDefaultWindowSurface_sys()
QWidget * qt_mac_modal_blocked(QWidget *)
void setAlphaF(qreal alpha)
Sets the alpha of this color to alpha.
Definition: qcolor.cpp:1117
QPoint pos
the position of the widget within its parent widget
Definition: qwidget.h:163
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
void setClipping(bool enable)
Enables clipping if enable is true, or disables clipping if enable is false.
Definition: qpainter.cpp:2517
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
QPaintEngine * paintEngine() const
Returns the widget&#39;s paint engine.
void setOpaque(bool opaque)
Definition: qwidget.cpp:2337
QWidget * currentTarget()
Definition: qdnd.cpp:273
QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition: qpoint.h:376
void setMask_sys(const QRegion &)
#define QT_MANGLE_NAMESPACE(name)
Definition: qglobal.h:106
QString iconText
Definition: qwidget_p.h:172
void createWinId(WId id=0)
Definition: qwidget.cpp:2574
float qt_mac_defaultDpi_x()
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
QPointer< QWidget > qt_last_native_mouse_receiver
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
SInt32 qt_mac_get_group_level(WindowClass wclass)
Definition: qwidget_mac.mm:538
bool qt_mac_app_fullscreen
void setRect(int x, int y, int w, int h)
Sets the coordinates of the rectangle&#39;s top-left corner to ({x}, {y}), and its size to the given widt...
Definition: qrect.h:400
struct CGPoint NSPoint
Qt::HANDLE macQDHandle() const
Returns the QuickDraw handle of the widget.
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
bool isFullScreen() const
Definition: qwidget.cpp:3153
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
Definition: qglobal.h:1219
void setBrush(const QBrush &brush)
Sets the painter&#39;s brush to the given brush.
Definition: qpainter.cpp:4171
const UInt32 kEventClassQt
Definition: qt_mac_p.h:92
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
Definition: qhash.h:330
unsigned int quint32
Definition: qglobal.h:938
The QMainWindow class provides a main application window.
Definition: qmainwindow.h:63
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
static bool qt_mac_raise_process
Definition: qwidget_mac.mm:154
static QWidget * keyboardGrabber()
Returns the widget that is currently grabbing the keyboard input.
uint opacity
Definition: qwidget_p.h:185
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
void setWidth(int w)
Sets the width of the rectangle to the given width.
Definition: qrect.h:442
void setPen(const QColor &color)
Sets the painter&#39;s pen to have style Qt::SolidLine, width 0 and the specified color.
Definition: qpainter.cpp:4047
struct OpaqueHIObjectRef * HIObjectRef
void scroll_sys(int dx, int dy)
QString objectName() const
void setWindowOpacity_sys(qreal opacity)
int height() const
Returns the height.
Definition: qsize.h:129
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
Definition: qnamespace.h:54
bool qt_mac_set_drawer_preferred_edge(QWidget *w, Qt::DockWidgetArea where)
Definition: qwidget_mac.mm:321
QPixmap * iconPixmap
Definition: qwidget_p.h:165
static bool macUpdateMenuBar()
Definition: qmenu_mac.mm:2055
QWExtra * extra
Definition: qwidget_p.h:700
bool qt_mac_insideKeyWindow(const QWidget *w)
Definition: qwidget_mac.mm:311
const QObjectList & children() const
Returns a list of child objects.
Definition: qobject.h:197
static void qt_mac_set_window_group(OSWindowRef window, Qt::WindowFlags flags, int level)
Definition: qwidget_mac.mm:549
void releaseKeyboard()
Releases the keyboard grab.
uint hasMask
Definition: qwidget_p.h:278
WId internalWinId() const
Returns the window system identifier of the widget, or 0 if the widget is not created yet...
Definition: qwidget.h:244
static void dispatchEnterLeave(QWidget *enter, QWidget *leave)
void resolveFont()
Determine which font is implicitly imposed on this widget by its ancestors and QApplication::font, resolve this against its own font (attributes from the implicit font are copied over).
Definition: qwidget.cpp:5074
QString caption
Definition: qwidget_p.h:171
virtual int metric(PaintDeviceMetric metric) const
void scrollRect(const QRect &, int dx, int dy)
void activateWindow()
Sets the top-level widget containing this widget to be the active window.
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
quint16 index
QPoint mapFromGlobal(const QPoint &) const
Translates the global screen coordinate pos to widget coordinates.
bool isMinimized() const
Definition: qwidget.cpp:3027
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
QObject * parent
Definition: qobject.h:92
static void qt_mac_destructView(OSViewRef view)
Definition: qwidget_mac.mm:235
void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow)
RgnHandle qt_mac_get_rgn()
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition: qicon.cpp:693
bool modal
Definition: qmenu_mac.mm:99
NSComparisonResult compareViews2Raise(id view1, id view2, void *context)
void createWinId()
Definition: qwidget.cpp:2626
qint32 minh
Definition: qwidget_p.h:265
uint posFromMove
Definition: qwidget_p.h:186
static const MacVersion MacintoshVersion
the version of the Macintosh operating system on which the application is run (Mac only)...
Definition: qglobal.h:1646
void translate(int dx, int dy)
Translates (moves) the region dx along the X axis and dy along the Y axis.
Definition: qregion.cpp:4116
void qt_event_request_window_change(QWidget *)
void setWinId(WId)
Definition: qwidget.cpp:1726
void Q_GUI_EXPORT qt_mac_set_raise_process(bool b)
Definition: qwidget_mac.mm:202
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove=0, bool alsoNonOpaque=false) const
Definition: qwidget.cpp:2139
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
int screenNumber(const QWidget *widget=0) const
bool qt_mac_can_clickThrough(const QWidget *w)
Definition: qwidget_mac.mm:280
struct OpaqueEventHandlerCallRef * EventHandlerCallRef
void updateIsOpaque()
Definition: qwidget.cpp:2272
Qt::WindowType windowType() const
Returns the window type of this widget.
Definition: qwidget.h:937
WId winId() const
Returns the window system identifier of the widget.
Definition: qwidget.cpp:2557
void createSysExtra()
uint fstrut_dirty
Definition: qwidget.h:126
QWExtra * extraData() const
Definition: qwidget_p.h:999
bool intersects(const QRect &r) const
Returns true if this rectangle intersects with the given rectangle (i.
Definition: qrect.cpp:1429
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize)
Invalidates the buffer when the widget is resized.
struct CGContext * CGContextRef
const QRect availableGeometry(int screen=-1) const
Qt::WindowFlags windowFlags() const
Window flags are a combination of a type (e.
Definition: qwidget.h:939
void createTLSysExtra()
Q_GUI_EXPORT QWidgetPrivate * qt_widget_private(QWidget *widget)
Definition: qwidget.cpp:12920
static EventTypeSpec window_events[]
Definition: qwidget_mac.mm:818
HIViewRef OSViewRef
Q_GUI_EXPORT QPoint qt_mac_posInWindow(const QWidget *w)
Definition: qwidget_mac.mm:380
Q_GUI_EXPORT OSViewRef qt_mac_effectiveview_for(const QWidget *w)
Definition: qwidget_mac.mm:424
static QGraphicsSystem * graphicsSystem()
bool isValid() const
Returns true if the rectangle is valid, otherwise returns false.
Definition: qrect.h:237
QPointer< QWidget > qt_last_mouse_receiver
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:60
The QPaintEvent class contains event parameters for paint events.
Definition: qevent.h:298
void qt_mac_update_cursor()
Definition: qcursor_mac.mm:201
#define XCOORD_MAX
Definition: qwidget_mac.mm:120
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
static CFStringRef kObjectQWidget
Definition: qwidget_mac.mm:167
void updateSystemBackground()
static void qt_mac_set_window_group_to_popup(OSWindowRef window)
Definition: qwidget_mac.mm:582
bool isOverlapped(const QRect &) const
Definition: qwidget.cpp:1877
The QIconDragEvent class indicates that a main icon drag has begun.
Definition: qevent.h:372
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
#define qPrintable(string)
Definition: qglobal.h:1750
static void leaveModal(QWidget *)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QWidget * qt_mac_find_window(OSWindowRef window)
Definition: qwidget_mac.mm:391
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition: qwidget.h:158
void setGeometry_sys(int, int, int, int, bool)
void stackUnder_sys(QWidget *)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
const QBrush & window() const
Returns the window (general background) brush of the current color group.
Definition: qpalette.h:135
#define QT_TRY
Definition: qglobal.h:1536
QPoint mapToGlobal(const QPoint &) const
Translates the widget coordinate pos to global screen coordinates.
WindowModality
Definition: qnamespace.h:1683
QRegion qt_mac_convert_mac_region(RgnHandle rgn)
void qt_mac_event_release(QWidget *w)
#define INT_MAX
void qt_mac_setMouseGrabCursor(bool set, QCursor *cursor=0)
Definition: qcursor_mac.mm:227
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
QRect effectiveRectFor(const QRect &rect) const
Definition: qwidget_p.h:658
WId winid
Definition: qwidget.h:117
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
bool end()
Ends painting.
Definition: qpainter.cpp:1929
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
static QWidget * dropWidget
#define kHIViewScrollRectAdjustInvalid
Definition: qwidget_mac.mm:129
qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, 0, &widgetToGetTouch)
struct OpaqueIconRef * IconRef
static Qt::KeyboardModifiers oldstate
Definition: qdnd_qws.cpp:87
Qt::HANDLE macCGHandle() const
Returns the CoreGraphics handle of the widget.
float CGFloat
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288
void qt_event_request_showsheet(QWidget *)
void setWindowIconText_sys(const QString &cap)
The QIcon class provides scalable icons in different modes and states.
Definition: qicon.h:60