Skip to content

Commit

Permalink
Added screen.watcher; part of #72.
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Degutis committed Jul 27, 2014
1 parent 493a65a commit d2001b7
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Hydra.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
948CAA0B19561D7300A27D9D /* timer.lua in Resources */ = {isa = PBXBuildFile; fileRef = 948CAA0A19561D7300A27D9D /* timer.lua */; };
94A1537C194D77A400F29F8F /* window.lua in Resources */ = {isa = PBXBuildFile; fileRef = 94A1537B194D77A400F29F8F /* window.lua */; };
94ABF0901980B5E900FA68E9 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94ABF08E1980B41300FA68E9 /* Security.framework */; };
94B6A9A11984974F00158B7B /* screen_watcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 94B6A9A01984974F00158B7B /* screen_watcher.m */; };
94BDB49C19094B7A00BD0553 /* application.m in Sources */ = {isa = PBXBuildFile; fileRef = 94BDB49B19094B7A00BD0553 /* application.m */; };
94BEAA58197EFD8300C4B1CF /* spaces.m in Sources */ = {isa = PBXBuildFile; fileRef = 94BEAA57197EFD8300C4B1CF /* spaces.m */; };
94C3693E194DD93600EE3A2D /* window.m in Sources */ = {isa = PBXBuildFile; fileRef = 94C3693D194DD93600EE3A2D /* window.m */; };
Expand Down Expand Up @@ -248,6 +249,7 @@
948CAA0A19561D7300A27D9D /* timer.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = timer.lua; sourceTree = "<group>"; };
94A1537B194D77A400F29F8F /* window.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = window.lua; sourceTree = "<group>"; };
94ABF08E1980B41300FA68E9 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
94B6A9A01984974F00158B7B /* screen_watcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = screen_watcher.m; sourceTree = "<group>"; };
94BDB49B19094B7A00BD0553 /* application.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = application.m; sourceTree = "<group>"; };
94BEAA57197EFD8300C4B1CF /* spaces.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = spaces.m; sourceTree = "<group>"; };
94C3693D194DD93600EE3A2D /* window.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = window.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -493,6 +495,7 @@
946AF2D51976B87A00A22EBF /* pasteboard.m */,
945212A1194D69E700217584 /* pathwatcher.m */,
94E8E79F194E0AB10064CF6C /* screen.m */,
94B6A9A01984974F00158B7B /* screen_watcher.m */,
94BEAA57197EFD8300C4B1CF /* spaces.m */,
948CA9FE1955AECC00A27D9D /* textgrid.m */,
944419C0194F4A51000A55A7 /* timer.m */,
Expand Down Expand Up @@ -636,6 +639,7 @@
943F212F195C527300066DCB /* hydra_settings.m in Sources */,
9445CA2219083251002568BB /* main.m in Sources */,
9445CA86190833C1002568BB /* ldebug.c in Sources */,
94B6A9A11984974F00158B7B /* screen_watcher.m in Sources */,
9445CA8C190833C1002568BB /* liolib.c in Sources */,
9445CA93190833C1002568BB /* loslib.c in Sources */,
9452129C194D5B8F00217584 /* hydra_autolaunch.m in Sources */,
Expand Down
13 changes: 13 additions & 0 deletions Hydra/API/screen_watcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// screen_watcher.h
// Hydra
//
// Created by Steven on 7/26/14.
// Copyright (c) 2014 Steven. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface screen_watcher : NSObject

@end
109 changes: 109 additions & 0 deletions Hydra/API/screen_watcher.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#import "helpers.h"

@interface HydraScreenWatcher : NSObject
@property lua_State* L;
@property int fn;
@end

@implementation HydraScreenWatcher
- (void) screensChanged:(id)bla {
lua_State* L = self.L;
lua_rawgeti(L, LUA_REGISTRYINDEX, self.fn);
if (lua_pcall(L, 0, 0, 0))
hydra_handle_error(L);
}
@end


typedef struct _screenwatcher_t {
bool running;
int fn;
void* obj;
} screenwatcher_t;

/// screen.watcher.new(fn) -> watcher
/// Creates a new screen-watcher that can be started; fn will be called when your screen layout changes in any way, whether by adding/removing/moving monitors or like whatever.
static int screen_watcher_new(lua_State* L) {
luaL_checktype(L, 1, LUA_TFUNCTION);

screenwatcher_t* screenwatcher = lua_newuserdata(L, sizeof(screenwatcher_t));
memset(screenwatcher, 0, sizeof(screenwatcher_t));

lua_pushvalue(L, 1);
screenwatcher->fn = luaL_ref(L, LUA_REGISTRYINDEX);

HydraScreenWatcher* object = [[HydraScreenWatcher alloc] init];
object.L = L;
object.fn = screenwatcher->fn;
screenwatcher->obj = (__bridge_retained void*)object;

luaL_getmetatable(L, "screen_watcher");
lua_setmetatable(L, -2);

return 1;
}

static int screen_watcher_start(lua_State* L) {
screenwatcher_t* screenwatcher = luaL_checkudata(L, 1, "screen_watcher");

if (screenwatcher->running) return 0;
screenwatcher->running = true;

[[NSNotificationCenter defaultCenter] addObserver:(__bridge id)screenwatcher->obj
selector:@selector(screensChanged:)
name:NSApplicationDidChangeScreenParametersNotification
object:nil];

return 0;
}

static int screen_watcher_stop(lua_State* L) {
screenwatcher_t* screenwatcher = luaL_checkudata(L, 1, "screen_watcher");

if (!screenwatcher->running) return 0;
screenwatcher->running = false;

[[NSNotificationCenter defaultCenter] removeObserver:(__bridge id)screenwatcher->obj];

return 0;
}

static int screen_watcher_stopall(lua_State* L) {
lua_getglobal(L, "screen");
lua_getfield(L, -1, "watcher");
lua_getfield(L, -1, "stop");
hydra_remove_all_handlers(L, "screen_watcher");
return 0;
}

static int screen_watcher_gc(lua_State* L) {
screenwatcher_t* screenwatcher = luaL_checkudata(L, 1, "screen_watcher");

luaL_unref(L, LUA_REGISTRYINDEX, screenwatcher->fn);

HydraScreenWatcher* object = (__bridge_transfer id)screenwatcher->obj;
object = nil;

return 0;
}

static luaL_Reg screen_watcherlib[] = {
{"new", screen_watcher_new},
{"start", screen_watcher_start},
{"stop", screen_watcher_stop},
{"stopall", screen_watcher_stopall},
{"__gc", screen_watcher_gc},
{}
};

int luaopen_screen_watcher(lua_State* L) {
luaL_newlib(L, screen_watcherlib);

lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");

lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, "screen_watcher");

return 1;
}
5 changes: 4 additions & 1 deletion Hydra/Bootstrapping/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ int main(int argc, const char * argv[]) {
int luaopen_pasteboard(lua_State* L);
int luaopen_pathwatcher(lua_State* L);
int luaopen_screen(lua_State* L);
int luaopen_screen_watcher(lua_State* L);
int luaopen_spaces(lua_State* L);
int luaopen_textgrid(lua_State* L);
int luaopen_timer(lua_State* L);
Expand Down Expand Up @@ -79,7 +80,9 @@ @implementation HydraAppDelegate
{}}},
{"pasteboard", luaopen_pasteboard},
{"pathwatcher", luaopen_pathwatcher},
{"screen", luaopen_screen},
{"screen", luaopen_screen, (hydralib[]){
{"watcher", luaopen_screen_watcher},
{}}},
{"spaces", luaopen_spaces},
{"textgrid", luaopen_textgrid},
{"timer", luaopen_timer},
Expand Down

0 comments on commit d2001b7

Please sign in to comment.