Skip to content

Commit

Permalink
Add a preference pane to install, start, stop, and configure metamove.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmgao committed Oct 20, 2013
1 parent 2937ebf commit 8f3f5dc
Show file tree
Hide file tree
Showing 16 changed files with 1,487 additions and 6 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# metamove

A utility for emulating XFree86-style Meta+click and drag window movement. It currently lacks any sort of user configurability, but I might get around to it eventually. The default bindings are Cmd-Shift-Click for window movement, and Option-Shift-Click for window resizing.
A utility for emulating XFree86-style Meta+click and drag window movement. The default bindings are Cmd-Shift-Click for window movement, and Option-Shift-Click for window resizing.

## Install
* chmod +x build.sh && ./build.sh
* Enable access for assistive devices in the OS X Accessibility preferences
* Run the binary
* Enable access for assistive devices in the OS X Accessibility preferences.
* Get the [latest release](https://github.com/jmgao/metamove/releases/tag/v0.2.0) and double click metamove.prefPane to install.
* Click Start!

## Uninstall
* Click stop in the preference pane, or run `launchctl unload ~/Library/LaunchAgents/us.insolit.metamove.plist`
* Delete ~/Library/LaunchAgents/us.insolit.metamove.plist
* Right click on metamove in the System Preferences and click remove
542 changes: 542 additions & 0 deletions metamove.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <ApplicationServices/ApplicationServices.h>

#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 0
Expand Down
4 changes: 2 additions & 2 deletions src/config.mm
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ void set_button(CFStringRef key, config_mouse_button button) {

config_mouse_button get_move_button(void) {
config_mouse_button result = get_button(move_button_key);
return result != config_mouse_button::unknown ? result : config_mouse_button::left;
return result != config_mouse_button::unknown ? result : config_mouse_button::disabled;
}

config_mouse_button get_resize_button(void) {
config_mouse_button result = get_button(resize_button_key);
return result != config_mouse_button::unknown ? result : config_mouse_button::left;
return result != config_mouse_button::unknown ? result : config_mouse_button::disabled;
}

void set_move_button(config_mouse_button button) {
Expand Down
34 changes: 34 additions & 0 deletions src/prefpane/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>us.insolit.metamove</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>metamove</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSMainNibFile</key>
<string>metamove_prefPane</string>
<key>NSPrefPaneIconFile</key>
<string>metamove_prefPane.tiff</string>
<key>NSPrefPaneIconLabel</key>
<string>metamove</string>
<key>NSPrincipalClass</key>
<string>metamove_prefPane</string>
</dict>
</plist>
25 changes: 25 additions & 0 deletions src/prefpane/NSTextFieldClickable.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

/*
* metamove - XFree86 window movement for OS X
* Copyright (C) 2013 jmgao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#import <AppKit/AppKit.h>

@interface NSTextFieldClickable : NSTextField
@end
32 changes: 32 additions & 0 deletions src/prefpane/NSTextFieldClickable.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* metamove - XFree86 window movement for OS X
* Copyright (C) 2013 jmgao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#import "NSTextFieldClickable.hh"

@implementation NSTextFieldClickable

- (void)
mouseDown:
(NSEvent *) event;
{
[self sendAction: [self action]
to: [self delegate]];
}

@end
69 changes: 69 additions & 0 deletions src/prefpane/PreferencePaneView.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#pragma once

/*
* metamove - XFree86 window movement for OS X
* Copyright (C) 2013 jmgao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>

@interface PreferencePaneView : NSView

@property (strong) IBOutlet NSSegmentedCell *startStopButton;

@property (strong) IBOutlet NSMatrix *moveRadioButtons;
@property (strong) IBOutlet NSButton *moveModifierControlButton;
@property (strong) IBOutlet NSButton *moveModifierOptionButton;
@property (strong) IBOutlet NSButton *moveModifierCommandButton;
@property (strong) IBOutlet NSButton *moveModifierShiftButton;

@property (strong) IBOutlet NSMatrix *resizeRadioButtons;
@property (strong) IBOutlet NSButton *resizeModifierControlButton;
@property (strong) IBOutlet NSButton *resizeModifierOptionButton;
@property (strong) IBOutlet NSButton *resizeModifierCommandButton;
@property (strong) IBOutlet NSButton *resizeModifierShiftButton;

@property (strong) IBOutlet NSTextField *versionLabel;
@property (strong) IBOutlet NSTextField *urlLabel;

- (void)
viewWillMoveToWindow:
(NSWindow *) newWindow;

- (void)
updateStatus;

- (void)
loadSettings;

- (void)
saveSettings;

- (IBAction)
startStopButtonClicked:
(id) sender;

- (IBAction)
configButtonClicked:
(id) sender;

- (IBAction)
urlClicked:
(id) sender;

@end
141 changes: 141 additions & 0 deletions src/prefpane/PreferencePaneView.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* metamove - XFree86 window movement for OS X
* Copyright (C) 2013 jmgao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#import "config.hpp"
#import "launchd_manager.hh"
#import "PreferencePaneView.hh"

@implementation PreferencePaneView

@synthesize startStopButton;

@synthesize moveRadioButtons;
@synthesize moveModifierControlButton;
@synthesize moveModifierOptionButton;
@synthesize moveModifierCommandButton;
@synthesize moveModifierShiftButton;

@synthesize resizeRadioButtons;
@synthesize resizeModifierControlButton;
@synthesize resizeModifierOptionButton;
@synthesize resizeModifierCommandButton;
@synthesize resizeModifierShiftButton;

@synthesize versionLabel;
@synthesize urlLabel;

- (void)
viewWillMoveToWindow:
(NSWindow *) newWindow
{
[self updateStatus];
[self loadSettings];
[versionLabel setStringValue: [NSString stringWithFormat: @"metamove v%s", VERSION_STRING]];
}

- (void)
updateStatus {
if ([launchd_manager isRunning]) {
[startStopButton setEnabled: false forSegment: 0];
[startStopButton setEnabled: true forSegment: 1];
[startStopButton setSelectedSegment: 0];
} else {
[startStopButton setEnabled: true forSegment: 0];
[startStopButton setEnabled: false forSegment: 1];
[startStopButton setSelectedSegment: 1];
}
}

- (void)
loadSettings
{
[moveRadioButtons selectCellWithTag: long(get_move_button())];
[moveModifierControlButton setState: get_move_modifiers() & kCGEventFlagMaskControl];
[moveModifierOptionButton setState: get_move_modifiers() & kCGEventFlagMaskAlternate];
[moveModifierCommandButton setState: get_move_modifiers() & kCGEventFlagMaskCommand];
[moveModifierShiftButton setState: get_move_modifiers() & kCGEventFlagMaskShift];

[resizeRadioButtons selectCellWithTag: long(get_resize_button())];
[resizeModifierControlButton setState: get_resize_modifiers() & kCGEventFlagMaskControl];
[resizeModifierOptionButton setState: get_resize_modifiers() & kCGEventFlagMaskAlternate];
[resizeModifierCommandButton setState: get_resize_modifiers() & kCGEventFlagMaskCommand];
[resizeModifierShiftButton setState: get_resize_modifiers() & kCGEventFlagMaskShift];
}

- (void)
saveSettings
{
CGEventMask modifiers = 0;
set_move_button(config_mouse_button([moveRadioButtons selectedTag]));
if ([moveModifierControlButton state]) modifiers |= kCGEventFlagMaskControl;
if ([moveModifierOptionButton state]) modifiers |= kCGEventFlagMaskAlternate;
if ([moveModifierCommandButton state]) modifiers |= kCGEventFlagMaskCommand;
if ([moveModifierShiftButton state]) modifiers |= kCGEventFlagMaskShift;
set_move_modifiers(modifiers);

modifiers = 0;
set_resize_button(config_mouse_button([resizeRadioButtons selectedTag]));
if ([resizeModifierControlButton state]) modifiers |= kCGEventFlagMaskControl;
if ([resizeModifierOptionButton state]) modifiers |= kCGEventFlagMaskAlternate;
if ([resizeModifierCommandButton state]) modifiers |= kCGEventFlagMaskCommand;
if ([resizeModifierShiftButton state]) modifiers |= kCGEventFlagMaskShift;
set_resize_modifiers(modifiers);
}

- (IBAction)
startStopButtonClicked:
(id) sender
{
if ([startStopButton isEnabledForSegment: 0]) {
// Start button was clicked
[launchd_manager start];
} else {
[launchd_manager stop];
}

[self updateStatus];
}

- (IBAction)
configButtonClicked:
(id) sender
{
[self saveSettings];

// Restart the daemon
static CFNotificationCenterRef distributed_center = CFNotificationCenterGetDistributedCenter();
CFNotificationCenterPostNotification(
distributed_center,
NOTIFICATION_SUICIDE,
NOTIFICATION_OBJECT,
(CFDictionaryRef) @{
@"sender" : @"metamove-prefpane",
@"reason" : @"Configuration changed"
},
true);
}

- (IBAction)
urlClicked:
(id) sender
{
[[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: @"https://github.com/jmgao/metamove"]];
}

@end
50 changes: 50 additions & 0 deletions src/prefpane/launchd_manager.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once

/*
* metamove - XFree86 window movement for OS X
* Copyright (C) 2013 jmgao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#import <Foundation/Foundation.h>

@interface launchd_manager : NSObject

+ (NSString *)
bundleLaunchdPlistPath;

+ (NSString *)
installedLaunchdPlistPath;

+ (bool)
isInstalled;

+ (void)
install;

+ (void)
uninstall;

+ (bool)
isRunning;

+ (void)
start;

+ (void)
stop;

@end
Loading

0 comments on commit 8f3f5dc

Please sign in to comment.