view Quasimode.m @ 33:c3e5b6b3bb4b default tip

Change default quasimode key to ctrl instead of option.
author Atul Varma <avarma@mozilla.com>
date Sat, 09 Oct 2010 03:00:09 -0700
parents 9490bb2373db
children
line wrap: on
line source

#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSURLRequest.h>
#import <Foundation/NSFileManager.h>
#import <AppKit/NSApplication.h>
#import <AppKit/NSColor.h>
#import <WebKit/WebFrame.h>
#import <WebKit/WebFrameView.h>
#import <WebKit/DOMEvents.h>

#import "Quasimode.h"
#import "JavaScriptQuasimode.h"
#import "QuasimodalEventTap.h"

@interface QuasimodeFrameLoadDelegate : NSObject {
  Quasimode *quasimode;
}
- (id)initWithQuasimode:(Quasimode *)qm;
- (void)webView:(WebView *)sender
  didClearWindowObject:(WebScriptObject *)windowObject
  forFrame:(WebFrame *)frame;
@end

@implementation QuasimodeFrameLoadDelegate
- (id)initWithQuasimode:(Quasimode *)qm {
  if (self = [super init]) {
    quasimode = qm;
  }
  return self;
}

- (void)webView:(WebView *)sender
  didClearWindowObject:(WebScriptObject *)windowObject
  forFrame:(WebFrame *)frame {
  JSQuasimodeInit(quasimode);
}
@end

@implementation Quasimode
- onEvent:(NSNotification *)notification {
  NSDictionary *info = [notification userInfo];
  DOMDocument *document = [[view mainFrame] DOMDocument];
  DOMEvent *event = [document createEvent: @"KeyboardEvent"];
  DOMKeyboardEvent *keyEvent = (DOMKeyboardEvent *) event;
  [keyEvent initKeyboardEvent: [info valueForKey: @"type"]
            canBubble: NO
            cancelable: NO
            view: [document defaultView]
            keyIdentifier: [info valueForKey: @"keyIdentifier"]
            keyLocation: [[info valueForKey: @"keyLocation"]
                           unsignedIntValue]
            ctrlKey: [[info valueForKey: @"ctrlKey"] boolValue]
            altKey: [[info valueForKey: @"altKey"] boolValue]
            shiftKey: [[info valueForKey: @"shiftKey"] boolValue]
            metaKey: [[info valueForKey: @"metaKey"] boolValue]];
  [document dispatchEvent: event];
}

- (id)initWithEventSource:(NSString *)sourceName
                      url:(NSURL *)url {
  if (self = [super init]) {
    eventSource = [sourceName copy];

    [[NSNotificationCenter defaultCenter]
      addObserver: self
      selector: @selector(onEvent:)
      name: @"QuasimodeEvent"
      object: eventSource];

    NSRect rect = {{20, 20},
                   {100, 100}};

    window = [[NSWindow alloc] initWithContentRect: rect
                               styleMask: NSBorderlessWindowMask
                               backing: NSBackingStoreBuffered
                               defer: YES];

    view = [[WebView alloc] initWithFrame: rect
                            frameName: nil
                            groupName: nil];

    QuasimodeFrameLoadDelegate
      *frameLoadDelegate = [[QuasimodeFrameLoadDelegate alloc]
                             initWithQuasimode: self];

    [view setFrameLoadDelegate: frameLoadDelegate];

    NSURLRequest *req = [
      NSURLRequest requestWithURL: url
      cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
      timeoutInterval: 5
    ];

    [view setDrawsBackground: NO];
    [[[view mainFrame] frameView] setAllowsScrolling: NO];
    [[view mainFrame] loadRequest: req];

    [window setOpaque: NO];
    [window setBackgroundColor: [NSColor colorWithCalibratedRed: 0.0
                                         green: 0.0
                                         blue: 0.0
                                         alpha: 0.0]];
    [window setContentView: view];
    [window setLevel: NSScreenSaverWindowLevel];
    [window makeKeyAndOrderFront: self];
  }
  return self;
}

- (NSWindow *)window {
  return window;
}

- (WebView *)view {
  return view;
}
@end

@interface QuasimodeWindowDelegate : NSObject {
}
- windowWillClose:(NSNotification *)notification;
@end

@implementation QuasimodeWindowDelegate
- windowWillClose:(NSNotification *)notification {
  [NSApp terminate: self];
}
@end

int main(int argc, const char *argv[])
{
  if (argc < 2) {
    printf("usage: %s <url-or-path-to-html>\n", argv[0]);
    return 1;
  }

  int retval = 0;
  CGEventFlags quasimodeKey = kCGEventFlagMaskControl;
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  [NSApplication sharedApplication];

  QuasimodalEventTap *tap = [[QuasimodalEventTap alloc]
                              initWithName: @"keyboard"
                              quasimodeKey: quasimodeKey];

  NSString *arg = [NSString stringWithUTF8String: argv[1]];
  NSURL *url = [NSURL URLWithString: arg];
  if (![url scheme]) {
    arg = [[arg stringByExpandingTildeInPath] stringByStandardizingPath];
    NSFileManager *fileManager = [NSFileManager defaultManager];

    if ([fileManager fileExistsAtPath: arg])
      url = [NSURL fileURLWithPath: arg];
    else {
      printf("File \"%s\" does not exist, nor does it appear "
             "to be a URL.\n", [arg UTF8String]);
      retval = 1;
    }
  }

  if (retval == 0) {
    printf("Creating quasimode with key 0x%x and UI at %s.\n",
           quasimodeKey,
           [[url absoluteString] UTF8String]);

    Quasimode *app = [[Quasimode alloc] initWithEventSource: @"keyboard"
                                        url: url];

    [[app window] setDelegate: [[QuasimodeWindowDelegate alloc] init]];

    [NSApp run];
  }

  [pool release];

  return retval;
}