diff dwt/widgets/Control.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents 642f460a0908
children cfa563df4fdd
line wrap: on
line diff
--- a/dwt/widgets/Control.d	Tue Oct 21 15:20:04 2008 +0200
+++ b/dwt/widgets/Control.d	Mon Dec 01 17:07:00 2008 +0100
@@ -1,5 +1,5 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -9,13 +9,14 @@
  *     IBM Corporation - initial API and implementation
  *     
  * Port to the D programming language:
- *     Jacob Carlborg <jacob.carlborg@gmail.com>
+ *     Jacob Carlborg <doob@me.com>
  *******************************************************************************/
 module dwt.widgets.Control;
 
 
 import dwt.DWT;
 import dwt.DWTException;
+import dwt.accessibility.ACC;
 import dwt.accessibility.Accessible;
 import dwt.events.ControlListener;
 import dwt.events.DragDetectListener;
@@ -40,18 +41,25 @@
 import dwt.graphics.Point;
 import dwt.graphics.Rectangle;
 import dwt.graphics.Region;
+import dwt.internal.cocoa.NSApplication;
+import dwt.internal.cocoa.NSArray;
+import dwt.internal.cocoa.NSAttributedString;
+import dwt.internal.cocoa.NSBezierPath;
+import dwt.internal.cocoa.NSColor;
 import dwt.internal.cocoa.NSControl;
+import dwt.internal.cocoa.NSDate;
 import dwt.internal.cocoa.NSEvent;
 import dwt.internal.cocoa.NSFont;
 import dwt.internal.cocoa.NSGraphicsContext;
+import dwt.internal.cocoa.NSInputManager;
+import dwt.internal.cocoa.NSMutableArray;
 import dwt.internal.cocoa.NSPoint;
 import dwt.internal.cocoa.NSRect;
 import dwt.internal.cocoa.NSSize;
 import dwt.internal.cocoa.NSString;
 import dwt.internal.cocoa.NSView;
-import dwt.internal.cocoa.NSWindow;
 import dwt.internal.cocoa.OS;
-import dwt.internal.cocoa.objc_super;
+import dwt.internal.cocoa.id;
 
 import tango.core.Thread;
 
@@ -89,6 +97,10 @@
  * IMPORTANT: This class is intended to be subclassed <em>only</em>
  * within the DWT implementation.
  * </p>
+ * 
+ * @see <a href="http://www.eclipse.org/swt/snippets/#control">Control snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
  */
 public abstract class Control : Widget , Drawable {
     
@@ -159,29 +171,156 @@
     createWidget ();
 }
 
-bool acceptsFirstResponder () {
-    objc_super super_struct = objc_super();
-    super_struct.receiver = view.id_;
-    super_struct.cls = cast(objc.Class) OS.objc_msgSend(view.id_, OS.sel_superclass);
-    return OS.objc_msgSendSuper(&super_struct, OS.sel_acceptsFirstResponder) !is null;
+int accessibilityActionNames(int /*long*/ id, int /*long*/ sel) {
+    if (accessible !is null) {
+        NSArray returnValue = accessible.internal_accessibilityActionNames(ACC.CHILDID_SELF);
+        if (returnValue !is null) return returnValue.id_;
+    }
+    
+    return super.accessibilityActionNames(id, sel);
+}
+
+int accessibilityAttributeNames(objc.id id, objc.SEL sel) {
+    
+    if (id is view.id_ || (cast(NSControl)view && (cast(NSControl)view).cell() !is null && (cast(NSControl)view).cell().id_ is id)) {
+        if (accessible !is null) {
+            
+            // First, see if the accessible is going to define a set of attributes for the control.
+            // If it does, return that.
+            NSArray returnValue = accessible.internal_accessibilityAttributeNames(ACC.CHILDID_SELF);
+            if (returnValue !is null) return returnValue.id;
+            
+            // If not, see if it will override or augment the standard list.
+            // Help, title, and description can be overridden.
+            NSMutableArray extraAttributes = NSMutableArray.arrayWithCapacity(3);
+            extraAttributes.addObject(OS.NSAccessibilityHelpAttribute);
+            extraAttributes.addObject(OS.NSAccessibilityDescriptionAttribute);
+            extraAttributes.addObject(OS.NSAccessibilityTitleAttribute);
+
+            for (int i = extraAttributes.count() - 1; i >= 0; i--) {
+                NSString attribute = new NSString(extraAttributes.objectAtIndex(i).id);
+                if (accessible.internal_accessibilityAttributeValue(attribute, ACC.CHILDID_SELF) is null) {
+                    extraAttributes.removeObjectAtIndex(i);
+                }
+            }
+
+            if (extraAttributes.count() > 0) {
+                int superResult = super.accessibilityAttributeNames(id, sel);
+                NSArray baseAttributes = new NSArray(superResult);
+                NSMutableArray mutableAttributes = NSMutableArray.arrayWithCapacity(baseAttributes.count() + 1);
+                mutableAttributes.addObjectsFromArray(baseAttributes);
+                
+                for (int i = 0; i < extraAttributes.count(); i++) {
+                    id currAttribute = extraAttributes.objectAtIndex(i);
+                    if (!mutableAttributes.containsObject(currAttribute)) {
+                        mutableAttributes.addObject(currAttribute);
+                    }
+                }
+                
+                return mutableAttributes.id;
+            }
+        }
+    }
+
+    return super.accessibilityAttributeNames(id, sel);
+}
+
+int accessibilityParameterizedAttributeNames(int /*long*/ id, int /*long*/ sel) {
+
+    if (id is view.id || (view instanceof NSControl && ((NSControl)view).cell() !is null && ((NSControl)view).cell().id is id)) {
+        if (accessible !is null) {
+            NSArray returnValue = accessible.internal_accessibilityParameterizedAttributeNames(ACC.CHILDID_SELF);
+            if (returnValue !is null) return returnValue.id;
+        }
+    }
+
+    return super.accessibilityParameterizedAttributeNames(id, sel);
 }
 
-bool becomeFirstResponder () {
-//TODO - query focusControl() in DWT.FocusIn/Out is the control
-    sendEvent (DWT.FocusIn);
-    objc_super super_struct = objc_super();
-    super_struct.receiver = view.id_;
-    super_struct.cls = cast(objc.Class) OS.objc_msgSend(view.id_, OS.sel_superclass);
-    return OS.objc_msgSendSuper(&super_struct, OS.sel_becomeFirstResponder) !is null;
+
+bool accessibilityIsAttributeSettable(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) {
+
+    // TODO: Carbon didn't support setting attributes, so for now Cocoa doesn't as well.
+    //  NSString attribute = new NSString(arg0);
+    //      
+    //  if (accessible !is null) {
+    //      return accessible.accessibilityIsAttributeSettable(attribute, ACC.CHILDID_SELF);
+    //  }   
+    //
+    //  return super.accessibilityIsAttributeSettable(id, sel, arg0);
+    return false;
+}
+
+int accessibilityFocusedUIElement(int /*long*/ id, int /*long*/ sel) {
+    id returnValue = null;
+
+    if (id is view.id || (view instanceof NSControl && ((NSControl)view).cell() !is null && ((NSControl)view).cell().id is id)) {
+        if (accessible !is null) {
+            returnValue = accessible.internal_accessibilityFocusedUIElement(ACC.CHILDID_SELF);
+        }
+    }
+
+    // If we had an accessible and it didn't handle the attribute request, let the
+    // superclass handle it.
+    if (returnValue is null)
+        return super.accessibilityFocusedUIElement(id, sel);
+    else
+        return returnValue.id;
 }
 
-bool resignFirstResponder () {
-//TODO - query focusControl() in DWT.FocusIn/Out is the control
-    sendEvent (DWT.FocusOut);
-    objc_super super_struct = objc_super();
-    super_struct.receiver = view.id_;
-    super_struct.cls = cast(objc.Class) OS.objc_msgSend(view.id_, OS.sel_superclass);
-    return OS.objc_msgSendSuper(&super_struct, OS.sel_resignFirstResponder) !is null;
+int accessibilityHitTest(int /*long*/ id, int /*long*/ sel, NSPoint point) {
+    id returnValue = null;
+
+    if (id is view.id || (view instanceof NSControl && ((NSControl)view).cell() !is null && ((NSControl)view).cell().id is id)) {
+        if (accessible !is null) {
+            returnValue = accessible.internal_accessibilityHitTest(point, ACC.CHILDID_SELF);
+        }
+    }
+
+    // If we had an accessible and it didn't handle the attribute request, let the
+    // superclass handle it.
+    if (returnValue is null)
+        return super.accessibilityHitTest(id, sel, point);
+    else
+        return returnValue.id;
+}
+
+int accessibilityAttributeValue(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) {
+    NSString attribute = new NSString(arg0);
+    int returnValue = 0;
+    id returnObject = null;
+    
+    if (accessible !is null) {
+        returnObject = accessible.internal_accessibilityAttributeValue(attribute, ACC.CHILDID_SELF);
+    }
+
+    // If we had an accessible and it didn't handle the attribute request, let the
+    // superclass handle it.
+    if (returnObject is null) {
+        returnValue = super.accessibilityAttributeValue(id, sel, arg0);
+    } else {
+        returnValue = returnObject.id;
+    }
+    
+    return returnValue;
+}
+
+int accessibilityAttributeValue_forParameter(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1) {
+    NSString attribute = new NSString(arg0);
+    
+    id returnValue = null;
+    
+    if (accessible !is null) {
+        id parameter = new id(arg1);
+        returnValue = accessible.internal_accessibilityAttributeValue_forParameter(attribute, parameter, ACC.CHILDID_SELF);
+    }
+    
+    // If we had an accessible and it didn't handle the attribute request, let the
+    // superclass handle it.
+    if (returnValue is null)
+        return super.accessibilityAttributeValue_forParameter(id, sel, arg0, arg1);
+    else
+        return returnValue.id;
 }
 
 /**
@@ -618,18 +757,22 @@
     checkWidget();
     int width = DEFAULT_WIDTH;
     int height = DEFAULT_HEIGHT;
-//  if (wHint !is DWT.DEFAULT) width = wHint;
-//  if (hHint !is DWT.DEFAULT) height = hHint;
-//  int border = getBorderWidth ();
-//  width += border * 2;
-//  height += border * 2;
-//  return new Point (width, height);
     if (cast(NSControl) topView()) {
         NSRect oldRect = topView().frame();
         (cast(NSControl)topView()).sizeToFit();
         NSRect newRect = topView().frame();
         topView().setFrame (oldRect);
-        return new Point (cast(int)newRect.width, cast(int)newRect.height);
+        width = cast(int) newRect.width;
+        height = cast(int)newRect.height;
+    }
+    int border = getBorderWidth ();
+    if (wHint !is DWT.DEFAULT) {
+        width = wHint;
+        width += border * 2;
+    }
+    if (hHint !is DWT.DEFAULT) {
+        height = hHint;
+        height += border * 2;
     }
     return new Point (width, height);
 }
@@ -663,6 +806,10 @@
     return parent.computeTabRoot ();
 }
 
+NSView contentView () {
+    return view;
+}
+
 void createWidget () {
     state |= DRAG_DETECT;
     checkOrientation (parent);
@@ -692,12 +839,42 @@
     return display.getSystemColor (DWT.COLOR_WIDGET_FOREGROUND);
 }
 
+void deregister () {
+    super.deregister ();
+    display.removeWidget (view);
+}
+
 void destroyWidget () {
     NSView view = topView ();
     view.removeFromSuperview ();
     releaseHandle ();
 }
 
+void doCommandBySelector (int /*long*/ id, int /*long*/ sel, int /*long*/ selector) {
+    if (view.window ().firstResponder ().id is id) {
+        NSEvent nsEvent = NSApplication.sharedApplication ().currentEvent ();
+        if (nsEvent !is null && nsEvent.type () is OS.NSKeyDown) {
+            // TODO is this workaround ok?
+            /*
+             * Feature in Cocoa.  Pressing Alt+UpArrow invokes doCommandBySelector 
+             * twice, with selectors moveBackward and moveToBeginningOfParagraph
+             * (Alt+DownArrow behaves similarly).  In order to avoid sending
+             * multiple events for these keys, do not send a KeyDown if the
+             * selector is moveToBeginningOfParagraph or moveToEndOfParagraph.
+             */
+            if (selector is OS.sel_moveToBeginningOfParagraph_|| selector is OS.sel_moveToEndOfParagraph_) return;
+
+            bool [] consume = new bool [1];
+            if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return;
+            if (isDisposed ()) return;
+            if (!sendKeyEvent (nsEvent, DWT.KeyDown)) return;
+            if (consume [0]) return;
+        }
+        if ((state & CANVAS) !is 0) return;
+    }
+    super.doCommandBySelector (id, sel, selector);
+}
+
 /**
  * Detects a drag and drop gesture.  This method is used
  * to detect a drag gesture when called from within a mouse
@@ -737,7 +914,7 @@
 public bool dragDetect (Event event) {
     checkWidget ();
     if (event is null) error (DWT.ERROR_NULL_ARGUMENT);
-    return dragDetect (event.button, event.count, event.stateMask, event.x, event.y);
+    return dragDetect ();
 }
 
 /**
@@ -779,38 +956,25 @@
 public bool dragDetect (MouseEvent event) {
     checkWidget ();
     if (event is null) error (DWT.ERROR_NULL_ARGUMENT);
-    return dragDetect (event.button, event.count, event.stateMask, event.x, event.y);
+    return dragDetect();
 }
 
-bool dragDetect (int button, int count, int stateMask, int x, int y) {
-    if (button !is 1 || count !is 1) return false;
-    if (!dragDetect (x, y, false, null)) return false;
-    return sendDragEvent (button, stateMask, x, y);
+bool dragDetect () {
+    NSApplication application = NSApplication.sharedApplication();
+    NSEvent event = application.nextEventMatchingMask(OS.NSLeftMouseDraggedMask, NSDate.dateWithTimeIntervalSinceNow(0.2), OS.NSDefaultRunLoopMode, false);
+    return (event !is null);
 }
 
 bool dragDetect (int x, int y, bool filter, bool [] consume) {
-//  Rect rect = new Rect ();
-//  int window = OS.GetControlOwner (handle);
-//  CGPoint pt = new CGPoint ();
-//  OS.HIViewConvertPoint (pt, handle, 0);
-//  x += cast(int) pt.x;
-//  y += cast(int) pt.y;
-//  OS.GetWindowBounds (window, cast(short) OS.kWindowStructureRgn, rect);
-//  x += rect.left;
-//  y += rect.top;
-//  dwt.internal.carbon.Point pt1 = new dwt.internal.carbon.Point ();
-//  pt1.h = cast(short) x;
-//  pt1.v = cast(short) y;
-//  return OS.WaitMouseMoved (pt1);
-    return false;
+    return dragDetect();
 }
 
 bool drawGripper (int x, int y, int width, int height, bool vertical) {
     return false;
 }
 
-void drawRect(objc.id id, NSRect rect) {
-    super.drawRect(id, rect);
+void drawWidget (objc.id id, NSRect rect) {
+    if (id !is view.id) return;
     if (!hooks (DWT.Paint) && !filters (DWT.Paint)) return;
 
     /* Send paint event */
@@ -830,12 +994,39 @@
 }
 
 void enableWidget (bool enabled) {
-    //TODO - other views
     if (cast(NSControl) view) {
         (cast(NSControl)view).setEnabled(enabled);
     }
 }
 
+void fillBackground (NSView view, NSGraphicsContext context, NSRect rect) {
+    Control control = findBackgroundControl();
+    if (control is null) control = this;
+    Image image = control.backgroundImage;
+    if (image !is null && !image.isDisposed()) {
+        context.saveGraphicsState();
+        NSColor.colorWithPatternImage(image.handle).setFill();
+        NSPoint phase = new NSPoint();
+        NSView controlView = control.view;
+        NSView contentView = controlView.window().contentView();
+        phase = controlView.convertPoint_toView_(phase, contentView);
+        phase.y = contentView.bounds().height - phase.y;
+        context.setPatternPhase(phase);
+        NSBezierPath.fillRect(rect);
+        context.restoreGraphicsState();
+        return;
+    }
+    Color background = control.getBackgroundColor ();
+    if (background !is null && !background.isDisposed ()) {
+        float [] color = background.handle;
+        context.saveGraphicsState();
+        NSColor.colorWithDeviceRed(color [0], color [1], color [2], getThemeAlpha()).setFill();
+        NSBezierPath.fillRect(rect);
+        context.restoreGraphicsState();
+        return;
+    }
+}
+
 Cursor findCursor () {
     if (cursor !is null) return cursor;
     return parent.findCursor ();
@@ -867,6 +1058,43 @@
 //  OS.ClearKeyboardFocus (window);
 }
 
+void flagsChanged (int /*long*/ id, int /*long*/ sel, int /*long*/ theEvent) {
+    if (view.window ().firstResponder ().id is id) {
+        if ((state & SAFARI_EVENTS_FIX) is 0) {
+            int mask = 0;
+            NSEvent nsEvent = new NSEvent (theEvent);
+            int /*long*/ modifiers = nsEvent.modifierFlags ();
+            int keyCode = Display.translateKey (nsEvent.keyCode ());
+            switch (keyCode) {
+                case DWT.ALT: mask = OS.NSAlternateKeyMask; break;
+                case DWT.CONTROL: mask = OS.NSControlKeyMask; break;
+                case DWT.COMMAND: mask = OS.NSCommandKeyMask; break;
+                case DWT.SHIFT: mask = OS.NSShiftKeyMask; break;
+                case DWT.CAPS_LOCK:
+                    Event event = new Event();
+                    event.keyCode = keyCode;
+                    setInputState (event, nsEvent, DWT.KeyDown);
+                    sendKeyEvent (DWT.KeyDown, event);
+                    setInputState (event, nsEvent, DWT.KeyUp);
+                    sendKeyEvent (DWT.KeyUp, event);
+                    break;
+            }
+            if (mask !is 0) {
+                int type = (mask & modifiers) !is 0 ? DWT.KeyDown : DWT.KeyUp;
+                Event event = new Event();
+                event.keyCode = keyCode;
+                setInputState (event, nsEvent, type);
+                if (!sendKeyEvent (type, event)) return;
+            }
+        }
+    }
+    super.flagsChanged (id, sel, theEvent);
+}
+
+NSView focusView () {
+    return view;
+}
+
 /**
  * Forces the receiver to have the <em>keyboard focus</em>, causing
  * all keyboard events to be delivered to it.
@@ -882,7 +1110,6 @@
  */
 public bool forceFocus () {
     checkWidget();
-//  if (display.focusEvent is DWT.FocusOut) return false;
     Decorations shell = menuShell ();
     shell.setSavedFocus (this);
     if (!isEnabled () || !isVisible ()/* || !isActive ()*/) return false;
@@ -890,10 +1117,10 @@
     shell.setSavedFocus (null);
     shell.bringToTop (false);
     if (isDisposed ()) return false;
-    view.window ().makeFirstResponder (view);
+    bool result = view.window ().makeFirstResponder (focusView ());
     if (isDisposed ()) return false;
     shell.setSavedFocus (this);
-    return hasFocus ();
+    return result;
 }
 
 /**
@@ -918,7 +1145,7 @@
     if (accessible is null) accessible = new_Accessible (this);
     return accessible;
 }
-    
+
 /**
  * Returns the receiver's background color.
  *
@@ -1011,13 +1238,19 @@
     return (state & DRAG_DETECT) !is 0;
 }
 
+NSBezierPath getClipping() {
+    return parent.getClipping ();
+}
+
 /**
  * Returns the receiver's cursor, or null if it has not been set.
  * <p>
  * When the mouse pointer passes over a control its appearance
  * is changed to match the control's cursor.
  * </p>
- * </ul>
+ *
+ * @return the receiver's cursor or <code>null</code>
+ *
  * @exception DWTException <ul>
  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
@@ -1215,6 +1448,19 @@
     return result;
 }
 
+/** 
+ * Returns the region that defines the shape of the control,
+ * or null if the control has the default shape.
+ *
+ * @return the region that defines the shape of the shell (or null)
+ *  
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.4
+ */
 public Region getRegion () {
     checkWidget ();
     return region;
@@ -1259,6 +1505,10 @@
     return new Point(cast(int)rect.width, cast(int)rect.height);
 }
 
+float getThemeAlpha () {
+    return 1 * parent.getThemeAlpha ();
+}
+
 /**
  * Returns the receiver's tool tip text, or null if it has
  * not been set.
@@ -1302,7 +1552,35 @@
 }
 
 bool hasFocus () {
-    return this is display.getFocusControl ();
+    return (view.window().firstResponder().id is view.id);
+}
+
+int /*long*/ hitTest (int /*long*/ id, int /*long*/ sel, NSPoint point) {
+    if ((state & DISABLED) !is 0) return 0;
+    return super.hitTest(id, sel, point);
+}
+
+bool insertText (int /*long*/ id, int /*long*/ sel, int /*long*/ string) {
+    if (view.window ().firstResponder ().id is id) {
+        NSEvent nsEvent = NSApplication.sharedApplication ().currentEvent ();
+        if (nsEvent !is null && nsEvent.type () is OS.NSKeyDown) {
+            NSString str = new NSString (string);
+            if (str.isKindOfClass (OS.objc_getClass ("NSAttributedString"))) {
+                str = new NSAttributedString (string).string ();
+            }
+            int length = (int)/*64*/str.length ();
+            char[] buffer = new char [length];
+            str.getCharacters(buffer);
+            for (int i = 0; i < buffer.length; i++) {
+                Event event = new Event ();
+                if (length is 1) setKeyState (event, DWT.KeyDown, nsEvent);
+                event.character = buffer [i];
+                if (!sendKeyEvent (nsEvent, DWT.KeyDown)) return false;
+            }
+        }
+        if ((state & CANVAS) !is 0) return true;
+    }
+    return super.insertText (id, sel, string);
 }
 
 /**  
@@ -1324,7 +1602,9 @@
     if (data !is null && data.paintRect !is null) {
         context = NSGraphicsContext.currentContext().id_;
     } else {
-        context = NSGraphicsContext.graphicsContextWithWindow(view.window()).id_;
+        NSGraphicsContext graphicsContext = NSGraphicsContext.graphicsContextWithWindow (view.window ());
+        display.addContext (graphicsContext);
+        context = graphicsContext.id_;
     }
     if (data !is null) {
         int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT;
@@ -1332,12 +1612,13 @@
             data.style |= style & (mask | DWT.MIRRORED);
         }
         data.device = display;
+        data.thread = display.thread;
         data.view = view;
         data.foreground = getForegroundColor ().handle;
         Control control = findBackgroundControl ();
         if (control is null) control = this;
         data.background = control.getBackgroundColor ().handle;
-        data.font = font !is null ? font : defaultFont ();       
+        data.font = font !is null ? font : defaultFont ();      
     }
     return context;
 }
@@ -1356,7 +1637,16 @@
  * @param data the platform specific GC data 
  */
 public void internal_dispose_GC (objc.id context, GCData data) {
-    checkWidget (); 
+    checkWidget ();
+    NSGraphicsContext graphicsContext = new NSGraphicsContext (context);
+    display.removeContext (graphicsContext);
+    if (data !is null) {
+        if (data.paintRect !is null) {
+            NSGraphicsContext.setCurrentContext (graphicsContext);
+        } else {
+            graphicsContext.flushGraphics ();
+        }
+    }
 }
 
 /**
@@ -1404,10 +1694,6 @@
  */
 public bool isFocusControl () {
     checkWidget();
-//  Control focusControl = display.focusControl;
-//  if (focusControl !is null && !focusControl.isDisposed ()) {
-//      return this is focusControl;
-//  }
     return hasFocus ();
 }
 
@@ -1467,6 +1753,10 @@
     return (code & (DWT.TRAVERSE_ARROW_PREVIOUS | DWT.TRAVERSE_ARROW_NEXT)) !is 0;
 }
 
+bool isTrim (NSView view) {
+    return false;
+}
+
 /**
  * Returns <code>true</code> if the receiver is visible and all
  * ancestors up to and including the receiver's nearest ancestor
@@ -1486,10 +1776,36 @@
     return getVisible () && parent.isVisible ();
 }
 
-objc.id menuForEvent (objc.id nsEvent) {
-    NSPoint pt = NSEvent.mouseLocation();   
-    NSWindow window = view.window();
-    pt.y = cast(int) (window.screen().frame().height - pt.y);
+void keyDown (objc.id id, objc.SEL sel, objc.id theEvent) {
+    if (view.window ().firstResponder ().id_ is id) {
+        bool textInput = OS.objc_msgSend (id, OS.sel_conformsToProtocol_, OS.objc_getProtocol ("NSTextInput")) !is null;
+        if (!textInput) {
+            NSEvent nsEvent = new NSEvent (theEvent);
+            bool [] consume = new bool [1];
+            if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return;
+            if (isDisposed ()) return;
+            if (!sendKeyEvent (nsEvent, DWT.KeyDown)) return;
+            if (consume [0]) return;
+        }
+    }
+    super.keyDown (id, sel, theEvent);
+}
+
+void keyUp (int /*long*/ id, int /*long*/ sel, int /*long*/ theEvent) {
+    if (view.window ().firstResponder ().id is id) {
+        NSEvent nsEvent = new NSEvent (theEvent);
+        if (!sendKeyEvent (nsEvent, DWT.KeyUp)) return;
+    }
+    super.keyUp (id, sel, theEvent);
+}
+
+void markLayout (bool changed, bool all) {
+    /* Do nothing */
+}
+
+int /*long*/ menuForEvent (int /*long*/ id, int /*long*/ sel, int /*long*/ theEvent) {
+    NSPoint pt = NSEvent.mouseLocation();
+    pt.y = (int) (display.getPrimaryFrame().height - pt.y);
     int x = cast(int) pt.x;
     int y = cast(int) pt.y;
     Event event = new Event ();
@@ -1504,133 +1820,36 @@
         }
         return menu.nsMenu.id_;
     }
-    objc_super super_struct = objc_super();
-    super_struct.receiver = view.id_;
-    super_struct.cls = cast(objc.Class) OS.objc_msgSend(view.id_, OS.sel_superclass);
-    return OS.objc_msgSendSuper(&super_struct, OS.sel_menuForEvent_1, nsEvent);
+    return super.menuForEvent (id, sel, theEvent);
 }
 
 Decorations menuShell () {
     return parent.menuShell ();
 }
 
-bool setInputState (Event event, NSEvent nsEvent, int type) {
-    int modifierFlags = nsEvent.modifierFlags();
-    if ((modifierFlags & OS.NSAlternateKeyMask) !is 0) event.stateMask |= DWT.ALT;
-    if ((modifierFlags & OS.NSShiftKeyMask) !is 0) event.stateMask |= DWT.SHIFT;
-    if ((modifierFlags & OS.NSControlKeyMask) !is 0) event.stateMask |= DWT.CONTROL;
-    if ((modifierFlags & OS.NSCommandKeyMask) !is 0) event.stateMask |= DWT.COMMAND;
-    
-    //WRONG
-    if ((modifierFlags & OS.NSLeftMouseDownMask) !is 0) event.stateMask |= DWT.BUTTON1;
-    if ((modifierFlags & OS.NSLeftMouseDraggedMask) !is 0) event.stateMask |= DWT.BUTTON1;
-    if ((modifierFlags & OS.NSLeftMouseUpMask) !is 0) event.stateMask |= DWT.BUTTON1;
-    if ((modifierFlags & OS.NSOtherMouseDownMask) !is 0) event.stateMask |= DWT.BUTTON2;
-    if ((modifierFlags & OS.NSOtherMouseDraggedMask) !is 0) event.stateMask |= DWT.BUTTON2;
-    if ((modifierFlags & OS.NSOtherMouseUpMask) !is 0) event.stateMask |= DWT.BUTTON1;
-    if ((modifierFlags & OS.NSRightMouseDownMask) !is 0) event.stateMask |= DWT.BUTTON3;
-    if ((modifierFlags & OS.NSRightMouseDraggedMask) !is 0) event.stateMask |= DWT.BUTTON3;
-    if ((modifierFlags & OS.NSRightMouseUpMask) !is 0) event.stateMask |= DWT.BUTTON3;
-    
-//  if (OS.GetKeyState (OS.VK_XBUTTON1) < 0) event.stateMask |= DWT.BUTTON4;
-//  if (OS.GetKeyState (OS.VK_XBUTTON2) < 0) event.stateMask |= DWT.BUTTON5;
-//  switch (type) {
-//      case DWT.MouseDown:
-//      case DWT.MouseDoubleClick:
-//          if (event.button is 1) event.stateMask &= ~DWT.BUTTON1;
-//          if (event.button is 2) event.stateMask &= ~DWT.BUTTON2;
-//          if (event.button is 3) event.stateMask &= ~DWT.BUTTON3;
-//          if (event.button is 4) event.stateMask &= ~DWT.BUTTON4;
-//          if (event.button is 5) event.stateMask &= ~DWT.BUTTON5;
-//          break;
-//      case DWT.MouseUp:
-//          if (event.button is 1) event.stateMask |= DWT.BUTTON1;
-//          if (event.button is 2) event.stateMask |= DWT.BUTTON2;
-//          if (event.button is 3) event.stateMask |= DWT.BUTTON3;
-//          if (event.button is 4) event.stateMask |= DWT.BUTTON4;
-//          if (event.button is 5) event.stateMask |= DWT.BUTTON5;
-//          break;
-//      case DWT.KeyDown:
-//      case DWT.Traverse:
-//          if (event.keyCode is DWT.ALT) event.stateMask &= ~DWT.ALT;
-//          if (event.keyCode is DWT.SHIFT) event.stateMask &= ~DWT.SHIFT;
-//          if (event.keyCode is DWT.CONTROL) event.stateMask &= ~DWT.CONTROL;
-//          break;
-//      case DWT.KeyUp:
-//          if (event.keyCode is DWT.ALT) event.stateMask |= DWT.ALT;
-//          if (event.keyCode is DWT.SHIFT) event.stateMask |= DWT.SHIFT;
-//          if (event.keyCode is DWT.CONTROL) event.stateMask |= DWT.CONTROL;
-//          break;
-//  }       
-    return true;
+void scrollWheel (int /*long*/ id, int /*long*/ sel, int /*long*/ theEvent) {
+    if (id is view.id) {
+        if (hooks (DWT.MouseWheel) || filters (DWT.MouseWheel)) {
+            NSEvent nsEvent = new NSEvent(theEvent);
+            if (nsEvent.deltaY() !is 0) {
+                if (!sendMouseEvent(nsEvent, DWT.MouseWheel, true)) {
+                    return;
+                }
+            }
+        }
+    }
+    super.scrollWheel(id, sel, theEvent);
 }
 
-void sendMouseEvent (NSEvent nsEvent, int type, int button) {
-    Event event = new Event ();
-    event.button = button;
-//  event.detail = detail;
-    event.count = nsEvent.clickCount();
-    NSPoint location = nsEvent.locationInWindow();
-    NSPoint point = view.convertPoint_fromView_(location, null);
-    event.x = cast(int) point.x;
-    event.y = cast(int) point.y;
-    setInputState (event, nsEvent, type);
-    sendEvent (type, event);
-}
-
-void mouseDown(objc.id theEvent) {
-    NSEvent nsEvent = new NSEvent (theEvent);
-    sendMouseEvent (nsEvent, DWT.MouseDown, 1);
-}
-
-void mouseDragged(objc.id theEvent) {
-    NSEvent nsEvent = new NSEvent (theEvent);
-    sendMouseEvent (nsEvent, DWT.MouseMove, 1);
-}
-
-void mouseUp(objc.id theEvent) {
-    NSEvent nsEvent = new NSEvent (theEvent);
-    sendMouseEvent (nsEvent, DWT.MouseUp, 1);
-}
-
-bool sendKeyEvent (Event event) {
-    sendEvent (event);
-    return event.doit;
+void mouseDown(int /*long*/ id, int /*long*/ sel, int /*long*/ theEvent) {
+    Display display = this.display;
+    display.trackingControl = this;
+    super.mouseDown(id, sel, theEvent);
+    display.trackingControl = null;
 }
 
-//TODO - missing modifier keys (see flagsChanged:)
-bool sendKeyEvent (NSEvent nsEvent, int type) {
-    if ((state & SAFARI_EVENTS_FIX) !is 0) return false;
-    int count = 0;
-    NSString keys = nsEvent.characters();
-    //TODO - check lowercase doesn't mangle char codes
-    NSString keyCodes = nsEvent.charactersIgnoringModifiers().lowercaseString();
-    char [] chars = new char [keys.length()];
-    for (int i=0; i<keys.length(); i++) {
-        Event event = new Event ();
-        int keyCode = Display.translateKey (keys.characterAtIndex (i) & 0xFFFF);
-        if (keyCode !is 0) {
-            event.keyCode = keyCode;
-        } else {
-            event.character = cast(char) keys.characterAtIndex (i);
-            //TODO - get unshifted values for Shift+1
-            event.keyCode = keyCodes.characterAtIndex (i);
-        }
-        setInputState (event, nsEvent, type);
-        if (!setKeyState(event, type, nsEvent)) return false;
-        if ((cast(Widget)this).sendKeyEvent (type, event)) {
-            chars [count++] = chars [i];
-        }
-    }
-//  if (count is 0) return false;
-    if (count !is keys.length () - 1) {
-//      OS.SetEventParameter (theEvent, OS.kEventParamKeyUnicodes, OS.typeUnicodeText, count * 2, chars);
-    }
-    return count is keys.length ();
-}
-
-void markLayout (bool changed, bool all) {
-    /* Do nothing */
+void moved () {
+    sendEvent (DWT.Move);
 }
 
 /**
@@ -1738,6 +1957,23 @@
     setSize (computeSize (DWT.DEFAULT, DWT.DEFAULT, changed));
 }
 
+/**
+ * Prints the receiver and all children.
+ * 
+ * @param gc the gc where the drawing occurs
+ * @return <code>true</code> if the operation was successful and <code>false</code> otherwise
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
+ * </ul>
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ * 
+ * @since 3.4
+ */
 public bool print (GC gc) {
     checkWidget ();
     if (gc is null) error (DWT.ERROR_NULL_ARGUMENT);
@@ -1827,23 +2063,31 @@
     view.setNeedsDisplayInRect(rect);
 }
 
+void register () {
+    super.register ();
+    display.addWidget (view, this);
+}
+
 void releaseHandle () {
     super.releaseHandle ();
-    if (view !is null) {
-        OS.objc_msgSend(view.id_, OS.sel_setTag_1, -1);
-        view.release();
-    }
+    if (view !is null) view.release();
     view = null;
     parent = null;
 }
 
 void releaseParent () {
-//  setVisible (topHandle (), false);
     parent.removeControl (this);
 }
 
 void releaseWidget () {
     super.releaseWidget ();
+    if (display.currentControl is this) {
+        display.currentControl = null;
+        display.timerExec(-1, display.hoverTimer);
+    }
+    if (display.grabControl is this) {
+        display.grabControl = null;
+    }
     if (menu !is null && !menu.isDisposed ()) {
         menu.dispose ();
     }
@@ -2158,6 +2402,10 @@
     eventTable.unhook (DWT.Traverse, listener);
 }
 
+void resized () {
+    sendEvent (DWT.Resize);
+}
+
 bool sendDragEvent (int button, int stateMask, int x, int y) {
     Event event = new Event ();
     event.button = button;
@@ -2168,38 +2416,18 @@
     return event.doit;
 }
 
-bool sendDragEvent (int button, int chord, int modifiers, int x, int y) {
-    Event event = new Event ();
-    switch (button) {
-        case 1: event.button = 1; break;
-        case 2: event.button = 3; break;
-        case 3: event.button = 2; break;
-        case 4: event.button = 4; break;
-        case 5: event.button = 5; break;
-    }
-    event.x = x;
-    event.y = y;
-    setInputState (event, DWT.DragDetect, chord, modifiers);
-    postEvent (DWT.DragDetect, event);
-    return event.doit;
+bool sendDragEvent (NSEvent nsEvent) {
+    return sendMouseEvent(nsEvent, DWT.DragDetect, true);
 }
 
 void sendFocusEvent (int type, bool post) {
     Display display = this.display;
     Shell shell = getShell ();
-    /*
-    * Feature in the Macintosh.  GetKeyboardFocus() returns NULL during
-    * kEventControlSetFocusPart if the focus part is not kControlFocusNoPart.
-    * The fix is to remember the focus control and return it during
-    * kEventControlSetFocusPart.
-    */
-//  display.focusControl = this;
-//  display.focusEvent = type;
     if (post) {
         postEvent (type);
     } else {
         sendEvent (type);
-    }   
+    }
     /*
     * It is possible that the shell may be
     * disposed at this point.  If this happens
@@ -2218,58 +2446,59 @@
                 break;
         }
     }
-//  display.focusEvent = DWT.None;
-//  display.focusControl = null;
-}
-
-bool sendMouseEvent (int type, short button, int count, int detail, bool send, int theEvent) {
-//  CGPoint pt = new CGPoint ();
-//  OS.GetEventParameter (theEvent, OS.kEventParamWindowMouseLocation, OS.typeHIPoint, null, CGPoint.sizeof, null, pt);
-//  OS.HIViewConvertPoint (pt, 0, handle);
-//  int x = cast(int) pt.x;
-//  int y = cast(int) pt.y;
-//  display.lastX = x;
-//  display.lastY = y;
-//  int [] chord = new int [1];
-//  OS.GetEventParameter (theEvent, OS.kEventParamMouseChord, OS.typeUInt32, null, 4, null, chord);
-//  int [] modifiers = new int [1];
-//  OS.GetEventParameter (theEvent, OS.kEventParamKeyModifiers, OS.typeUInt32, null, 4, null, modifiers);
-//  return sendMouseEvent (type, button, count, detail, send, chord [0], cast(short) x, cast(short) y, modifiers [0]);
-    return false;
 }
 
-bool sendMouseEvent (int type, short button, int count, bool send, int chord, short x, short y, int modifiers) {
-    return sendMouseEvent (type, button, count, 0, send, chord, x, y, modifiers);
-}
-
-bool sendMouseEvent (int type, short button, int count, int detail, bool send, int chord, short x, short y, int modifiers) {
-    if (!hooks (type) && !filters (type)) return true;
+bool sendMouseEvent (NSEvent nsEvent, int type, bool send) {
+    NSInputManager manager = NSInputManager.currentInputManager ();
+    if (manager !is null && manager.wantsToHandleMouseEvents ()) {
+        if (manager.handleMouseEvent (nsEvent)) {
+            return true;
+        }
+    }
+    Shell shell = null;
     Event event = new Event ();
-    switch (button) {
-        case 1: event.button = 1; break;
-        case 2: event.button = 3; break;
-        case 3: event.button = 2; break;
-        case 4: event.button = 4; break;
-        case 5: event.button = 5; break;
+    switch (type) {
+        case DWT.MouseDown:
+            shell = getShell ();
+            //FALL THROUGH
+        case DWT.MouseUp:
+        case DWT.MouseDoubleClick:
+            int button = (int)/*64*/nsEvent.buttonNumber();
+            switch (button) {
+                case 0: event.button = 1; break;
+                case 1: event.button = 3; break;
+                case 2: event.button = 2; break;
+                case 3: event.button = 4; break;
+                case 4: event.button = 5; break;
+            }
+            break;
+        case DWT.MouseWheel:
+            event.detail = DWT.SCROLL_LINE;
+            float /*double*/ delta = nsEvent.deltaY();
+            event.count = delta > 0 ? Math.max (1, (int)delta) : Math.min (-1, (int)delta);
+            break;
     }
-    event.x = x;
-    event.y = y;
-    event.count = count;
-    event.detail = detail;
-    setInputState (event, type, chord, modifiers);
+    if (event.button !is 0) event.count = (int)/*64*/nsEvent.clickCount();
+    NSPoint windowPoint;
+    if (nsEvent is null || nsEvent.type() is OS.NSMouseMoved) {
+        windowPoint = view.window().convertScreenToBase(NSEvent.mouseLocation()); 
+    } else {
+        windowPoint = nsEvent.locationInWindow();
+    }
+    NSPoint point = view.convertPoint_fromView_(windowPoint, null);
+    event.x = (int) point.x;
+    event.y = (int) point.y;
+    setInputState (event, nsEvent, type);
     if (send) {
         sendEvent (type, event);
         if (isDisposed ()) return false;
     } else {
         postEvent (type, event);
     }
+    if (shell !is null) shell.setActiveControl(this);
     return event.doit;
 }
 
-bool sendMouseWheel (short wheelAxis, int wheelDelta) {
-    return false;
-}
-
 void setBackground () {
 //  redrawWidget (handle, false);
 }
@@ -2378,44 +2607,26 @@
     setBounds (x, y, Math.max (0, width), Math.max (0, height), true, true);
 }
 
-int setBounds (int x, int y, int width, int height, bool move, bool resize) {
-    int result = 0;
+void setBounds (int x, int y, int width, int height, bool move, bool resize) {
     NSView topView = topView();
-    NSRect rect = topView.frame();
     if (move && resize) {
-        if (rect.x !is x || rect.y !is y) result |= MOVED;
-        if (rect.width !is width || rect.height !is height) result |= RESIZED;
-        if (result !is 0) {
-            rect.x = x;
-            rect.y = y;
-            rect.width = width;
-            rect.height = height;
-            topView.setFrame (rect);
-        }
+        NSRect rect = new NSRect();
+        rect.x = x;
+        rect.y = y;
+        rect.width = width;
+        rect.height = height;
+        topView.setFrame (rect);
     } else if (move) {
-        if (rect.x !is x || rect.y !is y) {
-            result |= MOVED;
             NSPoint point = NSPoint();
-            point.x = x;
-            point.y = y;
-            topView.setFrameOrigin(point);
-        }
+        point.x = x;
+        point.y = y;
+        topView.setFrameOrigin(point);
     } else if (resize) {
-        if (rect.width !is width || rect.height !is height) {
-            result |= RESIZED;
             NSSize size = NSSize();
-            size.width = width;
-            size.height = height;
-            topView.setFrameSize(size);
-        }
+        size.width = width;
+        size.height = height;
+        topView.setFrameSize(size);
     }
-    if ((result & MOVED) !is 0) {
-        sendEvent(DWT.Move);
-    }
-    if ((result & RESIZED) !is 0) {
-        sendEvent(DWT.Resize);
-    }
-    return result;
 }
 
 /**
@@ -2445,7 +2656,8 @@
 /**
  * If the argument is <code>true</code>, causes the receiver to have
  * all mouse events delivered to it until the method is called with
- * <code>false</code> as the argument.
+ * <code>false</code> as the argument.  Note that on some platforms,
+ * a mouse button must currently be down for capture to be assigned.
  *
  * @param capture <code>true</code> to capture the mouse, and <code>false</code> to release it
  *
@@ -2481,8 +2693,8 @@
     checkWidget();
     if (cursor !is null && cursor.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
     this.cursor = cursor;
-    //TODO null
-//  view.addCursorRect(view.frame(), cursor.handle);
+    if (!isEnabled()) return;
+    display.setCursor (display.currentControl);
 }
 
 void setDefaultFont () {
@@ -2531,10 +2743,8 @@
     Control control = null;
     bool fixFocus_ = false;
     if (!enabled) {
-//      if (display.focusEvent !is DWT.FocusOut) {
-            control = display.getFocusControl ();
-            fixFocus_ = isFocusAncestor (control);
-//      }
+        control = display.getFocusControl ();
+        fixFocus = isFocusAncestor (control);
     }
     if (enabled) {
         state &= ~DISABLED;
@@ -2641,6 +2851,32 @@
 //  OS.SetControlFontStyle (control, fontStyle);
 }
 
+void setFrameOrigin (int /*long*/ id, int /*long*/ sel, NSPoint point) {
+    NSView topView = topView ();
+    if (topView.id !is id) {
+        super.setFrameOrigin(id, sel, point);
+        return;
+    }
+    NSRect frame = topView.frame();
+    super.setFrameOrigin(id, sel, point);
+    if (frame.x !is point.x || frame.y !is point.y) {
+        moved ();
+    }
+}
+
+void setFrameSize (int /*long*/ id, int /*long*/ sel, NSSize size) {
+    NSView topView = topView ();
+    if (topView.id !is id) {
+        super.setFrameSize(id, sel, size);
+        return;
+    }
+    NSRect frame = topView.frame();
+    super.setFrameSize(id, sel, size);
+    if (frame.width !is size.width || frame.height !is size.height) {
+        resized ();
+    }
+}
+
 /**
  * Sets the layout data associated with the receiver to the argument.
  * 
@@ -2765,10 +3001,11 @@
         Menu [] menus = oldShell.findMenus (this);
         fixChildren (newShell, oldShell, newDecorations, oldDecorations, menus);
     }
-//  int topHandle = topHandle ();
-//  OS.HIViewAddSubview (parent.handle, topHandle);
-//  OS.HIViewSetVisible (topHandle, (state & HIDDEN) is 0);
-//  OS.HIViewSetZOrder (topHandle, OS.kHIViewZOrderBelow, 0);
+    NSView topView = topView ();
+    topView.retain();
+    topView.removeFromSuperview();
+    parent.contentView().addSubview(topView, OS.NSWindowBelow, null);
+    topView.release();
     this.parent = parent;
     return true;
 }
@@ -2813,6 +3050,23 @@
     }
 }
 
+/**
+ * Sets the shape of the control to the region specified
+ * by the argument.  When the argument is null, the
+ * default shape of the control is restored.
+ *
+ * @param region the region that defines the shape of the control (or null)
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
+ * </ul>  
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 3.4
+ */
 public void setRegion (Region region) {
     checkWidget ();
     if (region !is null && region.isDisposed()) error (DWT.ERROR_INVALID_ARGUMENT);
@@ -2941,10 +3195,8 @@
     Control control = null;
     bool fixFocus_ = false;
     if (!visible) {
-//      if (display.focusEvent !is DWT.FocusOut) {
-            control = display.getFocusControl ();
-            fixFocus_ = isFocusAncestor (control);
-//      }
+        control = display.getFocusControl ();
+        fixFocus = isFocusAncestor (control);
     }
     topView().setHidden(!visible);
     if (!visible) {
@@ -2960,21 +3212,15 @@
 }
 
 void setZOrder () {
-//  int topHandle = topHandle ();
-//  int parentHandle = parent.handle;
-//  OS.HIViewAddSubview (parentHandle, topHandle);
-//  OS.HIViewSetZOrder (topHandle, OS.kHIViewZOrderBelow, 0);
-//  Rect rect = getInset ();
-//  rect.right = rect.left;
-//  rect.bottom = rect.top;
-//  OS.SetControlBounds (topHandle, rect);
+    NSView topView = topView ();
+    parent.contentView().addSubview(topView, OS.NSWindowBelow, null);
 }
 
 void setZOrder (Control control, bool above) {
     NSView otherView = control is null ? null : control.topView ();
     view.retain();
     view.removeFromSuperview();
-    parent.contentView().addSubview_positioned_relativeTo_(view, above ? NSWindowAbove : NSWindowBelow, otherView);
+    parent.contentView().addSubview(view, above ? NSWindowAbove : NSWindowBelow, otherView);
     view.release();
 }
 
@@ -3101,7 +3347,7 @@
             break;
         }
         case 48: /* Tab */ {
-            int modifiers = display.lastModifiers;
+            int /*long*/ modifiers = theEvent.modifierFlags ();
             bool next = (modifiers & OS.NSShiftKeyMask) is 0;
             detail = next ? DWT.TRAVERSE_TAB_NEXT : DWT.TRAVERSE_TAB_PREVIOUS;
             break;
@@ -3117,10 +3363,9 @@
         case 116: /* Page up */
         case 121: /* Page down */ {
             all = true;
-//          int [] modifiers = new int [1];
-//          OS.GetEventParameter (theEvent, OS.kEventParamKeyModifiers, OS.typeUInt32, null, 4, null, modifiers);
-//          if ((modifiers [0] & OS.controlKey) is 0) return false;
-//          detail = key is 121 /* Page down */ ? DWT.TRAVERSE_PAGE_NEXT : DWT.TRAVERSE_PAGE_PREVIOUS;
+            int /*long*/ modifiers = theEvent.modifierFlags ();
+            if ((modifiers & OS.NSControlKeyMask) is 0) return false;
+            detail = key is 121 /* Page down */ ? DWT.TRAVERSE_PAGE_NEXT : DWT.TRAVERSE_PAGE_PREVIOUS;
             break;
         }
         default:
@@ -3144,7 +3389,7 @@
 }
 
 int traversalCode (short key, NSEvent theEvent) {
-    int code = DWT.TRAVERSE_RETURN | DWT.TRAVERSE_TAB_NEXT | DWT.TRAVERSE_TAB_PREVIOUS;
+    int code = DWT.TRAVERSE_RETURN | DWT.TRAVERSE_TAB_NEXT | DWT.TRAVERSE_TAB_PREVIOUS | DWT.TRAVERSE_PAGE_NEXT | DWT.TRAVERSE_PAGE_PREVIOUS;
     Shell shell = getShell ();
     if (shell.parent !is null) code |= DWT.TRAVERSE_ESCAPE;
     return code;
@@ -3292,7 +3537,7 @@
 void update (bool all) {
 //  checkWidget();
     //TODO - not all
-//  OS.HIViewRender (handle);
+    view.displayIfNeeded ();
 }
 
 void updateBackgroundMode () {