1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 /****************************************************************************
43 NB: This is not a header file, dispite the file name suffix. This file is
44 included directly into the source code of qcocoawindow_mac.mm and
45 qcocoapanel_mac.mm to avoid manually doing copy and paste of the exact
46 same code needed at both places. This solution makes it more difficult
47 to e.g fix a bug in qcocoawindow_mac.mm, but forget to do the same in
49 The reason we need to do copy and paste in the first place, rather than
50 resolve to method overriding, is that QCocoaPanel needs to inherit from
51 NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel).
52 ****************************************************************************/
54 // WARNING: Don't include any header files from within this file. Put them
55 // directly into qcocoawindow_mac_p.h and qcocoapanel_mac_p.h
58 extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
59 extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
60 extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp
61 extern void qt_event_request_window_change(QWidget *); // qapplication_mac.mm
62 extern void qt_mac_send_posted_gl_updates(QWidget *widget); // qapplication_mac.mm
64 Q_GLOBAL_STATIC(QPointer<QWidget>, currentDragTarget);
67 - (id)initWithContentRect:(NSRect)contentRect
68 styleMask:(NSUInteger)windowStyle
69 backing:(NSBackingStoreType)bufferingType
70 defer:(BOOL)deferCreation
72 self = [super initWithContentRect:contentRect styleMask:windowStyle
73 backing:bufferingType defer:deferCreation];
75 currentCustomDragTypes = 0;
82 delete currentCustomDragTypes;
86 - (BOOL)canBecomeKeyWindow
88 QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
90 return NO; // This should happen only for qt_root_win
91 if (QApplicationPrivate::isBlockedByModal(widget))
94 bool isToolTip = (widget->windowType() == Qt::ToolTip);
95 bool isPopup = (widget->windowType() == Qt::Popup);
96 return !(isPopup || isToolTip);
99 - (BOOL)canBecomeMainWindow
101 QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
103 return NO; // This should happen only for qt_root_win
107 bool isToolTip = (widget->windowType() == Qt::ToolTip);
108 bool isPopup = (widget->windowType() == Qt::Popup);
109 bool isTool = (widget->windowType() == Qt::Tool);
110 return !(isPopup || isToolTip || isTool);
113 - (void)becomeMainWindow
115 [super becomeMainWindow];
116 // Cocoa sometimes tell a hidden window to become the
117 // main window (and as such, show it). This can e.g
118 // happend when the application gets activated. If
119 // this is the case, we tell it to hide again:
120 if (![self isVisible])
121 [self orderOut:self];
124 - (void)toggleToolbarShown:(id)sender
126 macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
127 [super toggleToolbarShown:sender];
130 - (void)flagsChanged:(NSEvent *)theEvent
132 qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
133 [super flagsChanged:theEvent];
137 - (void)tabletProximity:(NSEvent *)tabletEvent
139 qt_dispatchTabletProximityEvent(tabletEvent);
142 - (void)terminate:(id)sender
144 // This function is called from the quit item in the menubar when this window
145 // is in the first responder chain (see also qtDispatcherToQAction above)
146 [NSApp terminate:sender];
149 - (void)setLevel:(NSInteger)windowLevel
151 // Cocoa will upon activating/deactivating applications level modal
152 // windows up and down, regardsless of any explicit set window level.
153 // To ensure that modal stays-on-top dialogs actually stays on top after
154 // the application is activated (and therefore stacks in front of
155 // other stays-on-top windows), we need to add this little special-case override:
156 QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
157 if (widget && widget->isModal() && (widget->windowFlags() & Qt::WindowStaysOnTopHint))
158 [super setLevel:NSPopUpMenuWindowLevel];
160 [super setLevel:windowLevel];
163 - (void)sendEvent:(NSEvent *)event
167 bool handled = false;
168 switch([event type]) {
170 // Cocoa sends move events to a parent and all its children under the mouse, much
171 // like Qt handles hover events. But we only want to handle the move event once, so
172 // to optimize a bit (since we subscribe for move event for all views), we handle it
173 // here before this logic happends. Note: it might be tempting to do this shortcut for
174 // all mouse events. The problem is that Cocoa does more than just find the correct view
175 // when sending the event, like raising windows etc. So avoid it as much as possible:
176 handled = qt_mac_handleMouseEvent(event, QEvent::MouseMove, Qt::NoButton, 0);
183 [super sendEvent:event];
184 qt_mac_handleNonClientAreaMouseEvent(self, event);
189 - (void)setInitialFirstResponder:(NSView *)view
191 // This method is called the first time the window is placed on screen and
192 // is the earliest point in time we can connect OpenGL contexts to NSViews.
193 QWidget *qwidget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
195 qt_event_request_window_change(qwidget);
196 qt_mac_send_posted_gl_updates(qwidget);
199 [super setInitialFirstResponder:view];
202 - (BOOL)makeFirstResponder:(NSResponder *)responder
204 // For some reason Cocoa wants to flip the first responder
205 // when Qt doesn't want to, sorry, but "No" :-)
206 if (responder == nil && qApp->focusWidget())
208 return [super makeFirstResponder:responder];
211 + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask
213 if (styleMask & QtMacCustomizeWindow)
214 return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class];
215 return [super frameViewClassForStyleMask:styleMask];
218 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
219 - (void)touchesBeganWithEvent:(NSEvent *)event;
221 QPoint qlocal, qglobal;
222 QWidget *widgetToGetTouch = 0;
223 qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, 0, &widgetToGetTouch);
224 if (!widgetToGetTouch)
227 bool all = widgetToGetTouch->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
228 qt_translateRawTouchEvent(widgetToGetTouch, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all));
231 - (void)touchesMovedWithEvent:(NSEvent *)event;
233 QPoint qlocal, qglobal;
234 QWidget *widgetToGetTouch = 0;
235 qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, 0, &widgetToGetTouch);
236 if (!widgetToGetTouch)
239 bool all = widgetToGetTouch->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
240 qt_translateRawTouchEvent(widgetToGetTouch, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all));
243 - (void)touchesEndedWithEvent:(NSEvent *)event;
245 QPoint qlocal, qglobal;
246 QWidget *widgetToGetTouch = 0;
247 qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, 0, &widgetToGetTouch);
248 if (!widgetToGetTouch)
251 bool all = widgetToGetTouch->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
252 qt_translateRawTouchEvent(widgetToGetTouch, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all));
255 - (void)touchesCancelledWithEvent:(NSEvent *)event;
257 QPoint qlocal, qglobal;
258 QWidget *widgetToGetTouch = 0;
259 qt_mac_getTargetForMouseEvent(event, QEvent::Gesture, qlocal, qglobal, 0, &widgetToGetTouch);
260 if (!widgetToGetTouch)
263 bool all = widgetToGetTouch->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
264 qt_translateRawTouchEvent(widgetToGetTouch, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all));
266 #endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
268 -(void)registerDragTypes
270 // Calling registerForDraggedTypes below is slow, so only do
271 // it once for each window, or when the custom types change.
272 QMacCocoaAutoReleasePool pool;
273 const QStringList& customTypes = qEnabledDraggedTypes();
274 if (currentCustomDragTypes == 0 || *currentCustomDragTypes != customTypes) {
275 if (currentCustomDragTypes == 0)
276 currentCustomDragTypes = new QStringList();
277 *currentCustomDragTypes = customTypes;
278 const NSString* mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName";
279 NSMutableArray *supportedTypes = [NSMutableArray arrayWithObjects:NSColorPboardType,
280 NSFilenamesPboardType, NSStringPboardType,
281 NSFilenamesPboardType, NSPostScriptPboardType, NSTIFFPboardType,
282 NSRTFPboardType, NSTabularTextPboardType, NSFontPboardType,
283 NSRulerPboardType, NSFileContentsPboardType, NSColorPboardType,
284 NSRTFDPboardType, NSHTMLPboardType, NSPICTPboardType,
285 NSURLPboardType, NSPDFPboardType, NSVCardPboardType,
286 NSFilesPromisePboardType, NSInkTextPboardType,
287 NSMultipleTextSelectionPboardType, mimeTypeGeneric, nil];
288 // Add custom types supported by the application.
289 for (int i = 0; i < customTypes.size(); i++) {
290 [supportedTypes addObject:qt_mac_QStringToNSString(customTypes[i])];
292 [self registerForDraggedTypes:supportedTypes];
296 - (void)removeDropData
304 - (void)addDropData:(id <NSDraggingInfo>)sender
306 [self removeDropData];
307 CFStringRef dropPasteboard = (CFStringRef) [[sender draggingPasteboard] name];
308 dropData = new QCocoaDropData(dropPasteboard);
311 - (void)changeDraggingCursor:(NSDragOperation)newOperation
313 static SEL action = nil;
314 static bool operationSupported = false;
316 action = NSSelectorFromString(@"operationNotAllowedCursor");
317 if ([NSCursor respondsToSelector:action]) {
318 operationSupported = true;
321 if (operationSupported) {
322 NSCursor *notAllowedCursor = [NSCursor performSelector:action];
323 bool isNotAllowedCursor = ([NSCursor currentCursor] == notAllowedCursor);
324 if (newOperation == NSDragOperationNone && !isNotAllowedCursor) {
325 [notAllowedCursor push];
326 } else if (newOperation != NSDragOperationNone && isNotAllowedCursor) {
327 [notAllowedCursor pop];
333 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
335 // The user dragged something into the window. Send a draggingEntered message
336 // to the QWidget under the mouse. As the drag moves over the window, and over
337 // different widgets, we will handle enter and leave events from within
338 // draggingUpdated below. The reason why we handle this ourselves rather than
339 // subscribing for drag events directly in QCocoaView is that calling
340 // registerForDraggedTypes on the views will severly degrade initialization time
341 // for an application that uses a lot of drag subscribing widgets.
343 NSPoint nswindowPoint = [sender draggingLocation];
344 NSPoint nsglobalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:nswindowPoint];
345 QPoint globalPoint = flipPoint(nsglobalPoint).toPoint();
347 QWidget *qwidget = QApplication::widgetAt(globalPoint);
348 *currentDragTarget() = qwidget;
350 return [super draggingEntered:sender];
351 if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false)
352 return NSDragOperationNone;
354 [self addDropData:sender];
356 QMimeData *mimeData = dropData;
357 if (QDragManager::self()->source())
358 mimeData = QDragManager::self()->dragPrivate()->data;
360 NSDragOperation nsActions = [sender draggingSourceOperationMask];
361 Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(nsActions);
362 QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
363 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
365 if ([sender draggingSource] != nil) {
366 // modifier flags might have changed, update it here since we don't send any input events.
367 QApplicationPrivate::modifier_buttons = qt_cocoaModifiers2QtModifiers([[NSApp currentEvent] modifierFlags]);
368 modifiers = QApplication::keyboardModifiers();
370 // when the source is from another application the above technique will not work.
371 modifiers = qt_cocoaDragOperation2QtModifiers(nsActions);
374 // send the drag enter event to the widget.
375 QPoint localPoint(qwidget->mapFromGlobal(globalPoint));
376 QDragEnterEvent qDEEvent(localPoint, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
377 QApplication::sendEvent(qwidget, &qDEEvent);
379 if (!qDEEvent.isAccepted()) {
380 // The enter event was not accepted. We mark this by removing
381 // the drop data so we don't send subsequent drag move events:
382 [self removeDropData];
383 [self changeDraggingCursor:NSDragOperationNone];
384 return NSDragOperationNone;
386 // Send a drag move event immediately after a drag enter event (as per documentation).
387 QDragMoveEvent qDMEvent(localPoint, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
388 qDMEvent.setDropAction(qDEEvent.dropAction());
389 qDMEvent.accept(); // accept by default, since enter event was accepted.
390 QApplication::sendEvent(qwidget, &qDMEvent);
392 if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction) {
393 // Since we accepted the drag enter event, the widget expects
394 // future drage move events.
395 nsActions = NSDragOperationNone;
396 // Save as ignored in the answer rect.
397 qDMEvent.setDropAction(Qt::IgnoreAction);
399 nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction());
402 QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent);
403 [self changeDraggingCursor:nsActions];
408 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
410 NSPoint nswindowPoint = [sender draggingLocation];
411 NSPoint nsglobalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:nswindowPoint];
412 QPoint globalPoint = flipPoint(nsglobalPoint).toPoint();
414 QWidget *qwidget = QApplication::widgetAt(globalPoint);
416 return [super draggingEntered:sender];
418 // First, check if the widget under the mouse has changed since the
419 // last drag move events. If so, we need to change target, and dispatch
420 // syntetic drag enter/leave events:
421 if (qwidget != *currentDragTarget()) {
422 if (*currentDragTarget() && dropData) {
424 QApplication::sendEvent(*currentDragTarget(), &de);
425 [self removeDropData];
427 return [self draggingEntered:sender];
430 if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false)
431 return NSDragOperationNone;
433 // If we have no drop data (which will be assigned inside draggingEntered), it means
434 // that the current drag target did not accept the enter event. If so, we ignore
435 // subsequent move events as well:
437 [self changeDraggingCursor:NSDragOperationNone];
438 return NSDragOperationNone;
441 // If the mouse is still within the accepted rect (provided by
442 // the application on a previous event), we follow the optimization
443 // and just return the answer given at that point:
444 NSDragOperation nsActions = [sender draggingSourceOperationMask];
445 QPoint localPoint(qwidget->mapFromGlobal(globalPoint));
446 if (qt_mac_mouse_inside_answer_rect(localPoint)
447 && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) {
448 NSDragOperation operation = QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
449 [self changeDraggingCursor:operation];
453 QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
454 Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions);
455 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
458 if ([sender draggingSource] != nil) {
459 QApplicationPrivate::modifier_buttons = qt_cocoaModifiers2QtModifiers([[NSApp currentEvent] modifierFlags]);
460 modifiers = QApplication::keyboardModifiers();
462 modifiers = qt_cocoaDragOperation2QtModifiers(nsActions);
465 QMimeData *mimeData = dropData;
466 if (QDragManager::self()->source())
467 mimeData = QDragManager::self()->dragPrivate()->data;
469 // Insert the same drop action on the event according to
470 // what the application told us it should be on the previous event:
471 QDragMoveEvent qDMEvent(localPoint, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
472 if (QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction != Qt::IgnoreAction
473 && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).buttons == qDMEvent.mouseButtons()
474 && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).modifiers == qDMEvent.keyboardModifiers())
475 qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
477 // Now, end the drag move event to the widget:
479 QApplication::sendEvent(qwidget, &qDMEvent);
481 NSDragOperation operation = qt_mac_mapDropAction(qDMEvent.dropAction());
482 if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction) {
483 // Ignore this event (we will still receive further
484 // notifications), save as ignored in the answer rect:
485 operation = NSDragOperationNone;
486 qDMEvent.setDropAction(Qt::IgnoreAction);
489 qt_mac_copy_answer_rect(qDMEvent);
490 [self changeDraggingCursor:operation];
495 - (void)draggingExited:(id <NSDraggingInfo>)sender
497 NSPoint nswindowPoint = [sender draggingLocation];
498 NSPoint nsglobalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:nswindowPoint];
499 QPoint globalPoint = flipPoint(nsglobalPoint).toPoint();
501 QWidget *qwidget = *currentDragTarget();
503 return [super draggingExited:sender];
507 QApplication::sendEvent(qwidget, &de);
508 [self removeDropData];
512 [self removeDropData];
513 *currentDragTarget() = 0;
514 [self changeDraggingCursor:NSDragOperationEvery];
517 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
519 QWidget *qwidget = *currentDragTarget();
523 *currentDragTarget() = 0;
524 NSPoint nswindowPoint = [sender draggingLocation];
525 NSPoint nsglobalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:nswindowPoint];
526 QPoint globalPoint = flipPoint(nsglobalPoint).toPoint();
528 [self addDropData:sender];
530 NSDragOperation nsActions = [sender draggingSourceOperationMask];
531 Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(nsActions);
532 QMimeData *mimeData = dropData;
534 if (QDragManager::self()->source())
535 mimeData = QDragManager::self()->dragPrivate()->data;
536 if (QDragManager::self()->object)
537 QDragManager::self()->dragPrivate()->target = qwidget;
539 QPoint localPoint(qwidget->mapFromGlobal(globalPoint));
540 QDropEvent de(localPoint, qtAllowed, mimeData,
541 QApplication::mouseButtons(), QApplication::keyboardModifiers());
542 QApplication::sendEvent(qwidget, &de);
544 if (QDragManager::self()->object)
545 QDragManager::self()->dragPrivate()->executed_action = de.dropAction();
547 return de.isAccepted();
550 // This is a hack and it should be removed once we find the real cause for
551 // the painting problems.
552 // We have a static variable that signals if we have been called before or not.
553 static bool firstDrawingInvocation = true;
555 // The method below exists only as a workaround to draw/not draw the baseline
556 // in the title bar. This is to support unifiedToolbar look.
558 // This method is very special. To begin with, it is a
559 // method that will get called only if we enable documentMode.
560 // Furthermore, it won't get called as a normal method, we swap
561 // this method with the normal implementation of drawRect in
562 // _NSThemeFrame. When this method is active, its mission is to
563 // first call the original drawRect implementation so the widget
564 // gets proper painting. After that, it needs to detect if there
565 // is a toolbar or not, in order to decide how to handle the unified
566 // look. The distinction is important since the presence and
567 // visibility of a toolbar change the way we enter into unified mode.
568 // When there is a toolbar and that toolbar is visible, the problem
569 // is as simple as to tell the toolbar not to draw its baseline.
570 // However when there is not toolbar or the toolbar is not visible,
571 // we need to draw a line on top of the baseline, because the baseline
572 // in that case will belong to the title. For this case we need to draw
573 // a line on top of the baseline.
574 // As usual, there is a special case. When we first are called, we might
575 // need to repaint ourselves one more time. We only need that if we
576 // didn't get the activation, i.e. when we are launched via the command
577 // line. And this only if the toolbar is visible from the beginning,
578 // so we have a special flag that signals if we need to repaint or not.
579 - (void)drawRectSpecial:(NSRect)rect
581 // Call the original drawing method.
582 [id(self) drawRectOriginal:rect];
583 NSWindow *window = [id(self) window];
584 NSToolbar *toolbar = [window toolbar];
586 // There is no toolbar, we have to draw a line on top of the line drawn by Cocoa.
587 macDrawRectOnTop((void *)window);
589 if([toolbar isVisible]) {
590 // We tell Cocoa to avoid drawing the line at the end.
591 if(firstDrawingInvocation) {
592 firstDrawingInvocation = false;
593 macSyncDrawingOnFirstInvocation((void *)window);
595 [toolbar setShowsBaselineSeparator:NO];
597 // There is a toolbar but it is not visible so
598 // we have to draw a line on top of the line drawn by Cocoa.
599 macDrawRectOnTop((void *)window);
604 - (void)drawRectOriginal:(NSRect)rect
607 // This method implementation is here to silenct the compiler.
608 // See drawRectSpecial for information.