totalspaces2 2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT_LICENCE +20 -0
- data/README.rdoc +65 -0
- data/lib/TSLib.h +256 -0
- data/lib/libtotalspaces2api.dylib +0 -0
- data/lib/totalspaces2.rb +575 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a133c5d3f23844aa9ca70332146796499c6e3b9e
|
4
|
+
data.tar.gz: 342ceaf3ec96f133b4e6b0a06e8f1a7400c24a4c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4455a450a3c33fa50fce7162d9ebca2285fcb10d1828132cdbbf99d9aa2c36f02f6e01d354a0efd6f58f89bb749429e35b400e7ad48ec1dedb79d8cac14d7ac6
|
7
|
+
data.tar.gz: 2f025c0a21fc74d0f166ed95d7cb0bab5c0d1ec955a7ce743a0e5893267353f7e0d01a31446d36c3f232bd73fec51bd785dc48f0aefe66ee073759f479d70408
|
data/MIT_LICENCE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Stephen Sykes
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
= TotalSpaces2 - Ruby API bindings for TotalSpaces2 from BinaryAge
|
2
|
+
|
3
|
+
== PRERELEASE: You will be able to use the API with versions 2.1 and above of totalspaces.
|
4
|
+
|
5
|
+
This gem enables you to get information from and to control {TotalSpaces2}[link:http://totalspaces.binaryage.com]
|
6
|
+
|
7
|
+
It is the officially supported way of using the API library libtotalspaces2api, and the required dylib
|
8
|
+
comes bundled with this gem. This gem uses {Ruby-FFI}[link:https://github.com/ffi/ffi] to call the functions in the dylib.
|
9
|
+
You'll need a sane ruby and compilation environment to install ruby-ffi - it probably won't install immediately with the
|
10
|
+
ruby that comes with Mavericks because none of the compilation tools are present. We use {homebrew}[link:http://mxcl.github.com/homebrew/]
|
11
|
+
and {rbenv}[link:https://github.com/sstephenson/rbenv/] to manage our ruby scripting environment.
|
12
|
+
|
13
|
+
You may use this gem in various ways. For instance, you could:
|
14
|
+
|
15
|
+
* Display a message or alert when a particular space is moved to
|
16
|
+
|
17
|
+
* Automatically change the name of spaces depending on what apps are in them
|
18
|
+
|
19
|
+
* Record which spaces certain windows are on, and restoring those windows to those spaces when the owning app restarts
|
20
|
+
|
21
|
+
* Trigger moving certain windows between spaces
|
22
|
+
|
23
|
+
API support, and support for this gem starts with TotalSpaces2 v2.0.12 The API is a premium feature,
|
24
|
+
and will only work with registered versions of TotalSpaces2.
|
25
|
+
|
26
|
+
== Download and installation
|
27
|
+
|
28
|
+
The latest version of the TotalSpaces2 gem can be installed with RubyGems:
|
29
|
+
|
30
|
+
% [sudo] gem install totalspaces2
|
31
|
+
|
32
|
+
Source code can be downloaded on GitHub
|
33
|
+
|
34
|
+
* https://github.com/binaryage/totalspaces2-api
|
35
|
+
|
36
|
+
|
37
|
+
== Documentation
|
38
|
+
|
39
|
+
{module TotalSpaces2}[link:http://binaryage.github.io/totalspaces2-api/ruby/rdoc/TotalSpaces2.html]
|
40
|
+
|
41
|
+
== Examples
|
42
|
+
require 'totalspaces2'
|
43
|
+
|
44
|
+
TotalSpaces2.on_space_change {|from, to, display_id| puts "Moving from space #{from} to space #{to}";}
|
45
|
+
|
46
|
+
TotalSpaces2.move_to_space(1)
|
47
|
+
|
48
|
+
current_space = TotalSpaces2.current_space
|
49
|
+
puts "Current space number: #{current_space}"
|
50
|
+
puts "Current space is called: #{TotalSpaces2.name_for_space(current_space)}"
|
51
|
+
|
52
|
+
TotalSpaces2.set_name_for_space(1, "Home")
|
53
|
+
|
54
|
+
== License
|
55
|
+
|
56
|
+
The TotalSpaces2 gem is released under the MIT license:
|
57
|
+
|
58
|
+
* http://www.opensource.org/licenses/MIT
|
59
|
+
|
60
|
+
The source code of the dylib is not available at this time.
|
61
|
+
|
62
|
+
|
63
|
+
== Support and feature requests
|
64
|
+
|
65
|
+
* http://discuss.binaryage.com
|
data/lib/TSLib.h
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
//
|
2
|
+
// TSLib.h
|
3
|
+
// totalspacesapi
|
4
|
+
//
|
5
|
+
// Created by Stephen Sykes on 27/1/13.
|
6
|
+
// Copyright (c) 2013 Stephen Sykes. All rights reserved.
|
7
|
+
//
|
8
|
+
// The API is a premium feature, and will only work with registered versions of TotalSpaces.
|
9
|
+
//
|
10
|
+
|
11
|
+
#ifndef totalspacesapi_tslib
|
12
|
+
#define totalspacesapi_tslib_h
|
13
|
+
|
14
|
+
#import <Foundation/Foundation.h>
|
15
|
+
|
16
|
+
#define TSAPI_MAX_SPACES 32
|
17
|
+
|
18
|
+
/*
|
19
|
+
* In case of comm error, all the functions apart from tsapi_libTotalSpacesVersion() will
|
20
|
+
* return an empty string, zero, false or a pointer to a struct containing zero spaces (in
|
21
|
+
* the case of tsapi_windowList).
|
22
|
+
* It is recommended to check that comms to TotalSpaces are working by, for instance,
|
23
|
+
* checking that tsapi_apiVersion() matches tsapi_libTotalSpacesVersion() when you initialize
|
24
|
+
* your app.
|
25
|
+
*
|
26
|
+
* Some actions such as renaming a space will cause the overview grid to be exited if it
|
27
|
+
* is showing at the time.
|
28
|
+
*/
|
29
|
+
|
30
|
+
/*
|
31
|
+
* The version of the API present in TotalSpaces.app.
|
32
|
+
*
|
33
|
+
* You must call tsapi_freeString when you have finished with the returned string.
|
34
|
+
*/
|
35
|
+
const char *tsapi_apiVersion();
|
36
|
+
|
37
|
+
/*
|
38
|
+
* The version number of TotalSpaces itself.
|
39
|
+
*
|
40
|
+
* You must call tsapi_freeString when you have finished with the returned string.
|
41
|
+
*/
|
42
|
+
const char *tsapi_totalSpacesVersion();
|
43
|
+
|
44
|
+
/*
|
45
|
+
* The version of the API dylib. This should match the string returned
|
46
|
+
* by tsapi_apiVersion().
|
47
|
+
*
|
48
|
+
* You must call tsapi_freeString when you have finished with the returned string.
|
49
|
+
*/
|
50
|
+
const char *tsapi_libTotalSpacesVersion();
|
51
|
+
|
52
|
+
/*
|
53
|
+
* Struct containing info about a display.
|
54
|
+
*/
|
55
|
+
struct tsapi_display {
|
56
|
+
CGDirectDisplayID displayId;
|
57
|
+
char *displayName;
|
58
|
+
size_t width;
|
59
|
+
size_t height;
|
60
|
+
};
|
61
|
+
|
62
|
+
/*
|
63
|
+
* Struct containing the count of spaces and a pointer to an
|
64
|
+
* array of CGDirectDisplayIDs.
|
65
|
+
*/
|
66
|
+
struct tsapi_displays {
|
67
|
+
unsigned int displaysCount;
|
68
|
+
struct tsapi_display *displays;
|
69
|
+
};
|
70
|
+
|
71
|
+
/*
|
72
|
+
* Return a pointer to a tsapi_displays struct containing information about all the displays.
|
73
|
+
*
|
74
|
+
* The first display in the list will be the main display. The main display is the display
|
75
|
+
* with its screen location at (0,0) in the global display coordinate space. In a system
|
76
|
+
* without display mirroring, the display with the menu bar is typically the main display.
|
77
|
+
*
|
78
|
+
* You must call tsapi_freeDisplayList when you have finished with this.
|
79
|
+
*/
|
80
|
+
struct tsapi_displays *tsapi_displayList();
|
81
|
+
|
82
|
+
/*
|
83
|
+
* Free a previously returned tsapi_displays struct
|
84
|
+
*/
|
85
|
+
void tsapi_freeDisplayList(struct tsapi_displays *displayList);
|
86
|
+
|
87
|
+
/*
|
88
|
+
* The number of the current space.
|
89
|
+
*
|
90
|
+
* If the current space is the dashboard, 0 is returned.
|
91
|
+
*/
|
92
|
+
unsigned int tsapi_currentSpaceNumberOnDisplay(CGDirectDisplayID displayID);
|
93
|
+
|
94
|
+
/*
|
95
|
+
* The name for the given space number.
|
96
|
+
*
|
97
|
+
* You must call tsapi_freeString when you have finished with the returned string.
|
98
|
+
*/
|
99
|
+
const char *tsapi_spaceNameForSpaceNumberOnDisplay(unsigned int spaceNumber, CGDirectDisplayID displayID);
|
100
|
+
|
101
|
+
/*
|
102
|
+
* The total number of spaces.
|
103
|
+
* This includes the dashboard if you have it set as a space, and any
|
104
|
+
* fullscreen apps.
|
105
|
+
*/
|
106
|
+
unsigned int tsapi_numberOfSpacesOnDisplay(CGDirectDisplayID displayID);
|
107
|
+
|
108
|
+
/*
|
109
|
+
* The number of columns defined in TotalSpaces layout preferences.
|
110
|
+
*/
|
111
|
+
unsigned int tsapi_definedColumnsOnDisplay(CGDirectDisplayID displayID);
|
112
|
+
|
113
|
+
/*
|
114
|
+
* Sets the number of columns in the TotalSpaces grid.
|
115
|
+
* Returns true on success, false if the new grid would exceed TSAPI_MAX_SPACES
|
116
|
+
* or if columns is zero.
|
117
|
+
* Note that the actual number of desktops present in the system is unchanged,
|
118
|
+
* you should call tsapi_addDesktops or tsapi_removeDesktops after calling this
|
119
|
+
* function.
|
120
|
+
*/
|
121
|
+
bool tsapi_setDefinedColumnsOnDisplay(unsigned int columns, CGDirectDisplayID displayID);
|
122
|
+
|
123
|
+
/*
|
124
|
+
* Call this to free strings returned by the TotalSpaces API.
|
125
|
+
*/
|
126
|
+
void tsapi_freeString(char *str);
|
127
|
+
|
128
|
+
/*
|
129
|
+
* Switch the display to the given space.
|
130
|
+
* Returns false if the space number is invalid.
|
131
|
+
*/
|
132
|
+
bool tsapi_moveToSpaceOnDisplay(unsigned int spaceNumber, CGDirectDisplayID displayID);
|
133
|
+
|
134
|
+
/*
|
135
|
+
* Set the name of a space.
|
136
|
+
* The maximum length is 255 bytes. The name should be in UTF-8.
|
137
|
+
* Returns true on success, false if the name was too long or the space number was invalid.
|
138
|
+
*/
|
139
|
+
bool tsapi_setNameForSpaceOnDisplay(unsigned int spaceNumber, char *name, CGDirectDisplayID displayID);
|
140
|
+
|
141
|
+
/*
|
142
|
+
* Type for space change callback.
|
143
|
+
*/
|
144
|
+
typedef void (*space_change_callback_t)(unsigned int fromSpaceNumber, unsigned int toSpaceNumber, CGDirectDisplayID displayID);
|
145
|
+
|
146
|
+
/*
|
147
|
+
* Set the function that will be called when the visible space changes.
|
148
|
+
* There is only one callback per process, registering a new callback will supercede any previous one.
|
149
|
+
*/
|
150
|
+
void tsapi_setSpaceWillChangeCallback(space_change_callback_t callback);
|
151
|
+
|
152
|
+
/*
|
153
|
+
* Cancel space change callbacks
|
154
|
+
*/
|
155
|
+
void tsapi_unsetSpaceWillChangeCallback();
|
156
|
+
|
157
|
+
/*
|
158
|
+
* Type for layout change callback
|
159
|
+
*/
|
160
|
+
typedef void (*space_layout_changed_callback_t)(void);
|
161
|
+
|
162
|
+
/*
|
163
|
+
* Set the function that will be called when the layout changes.
|
164
|
+
* This could be any change - for instance adding or removing a fullscreen, changing the name of a space,
|
165
|
+
* or a change of rows or columns.
|
166
|
+
* It indicates that you should re-request any information you are holding on the spaces.
|
167
|
+
* There is only one callback per process, registering a new callback will supercede any previous one.
|
168
|
+
*/
|
169
|
+
void tsapi_setLayoutChangedCallback(space_layout_changed_callback_t callback);
|
170
|
+
|
171
|
+
/*
|
172
|
+
* Cancel layout change callbacks.
|
173
|
+
*/
|
174
|
+
void tsapi_unsetLayoutChangedCallback();
|
175
|
+
|
176
|
+
/*
|
177
|
+
* Struct containing information about a window.
|
178
|
+
*/
|
179
|
+
struct tsapi_window {
|
180
|
+
char *appName;
|
181
|
+
unsigned int windowId;
|
182
|
+
bool isOnAllSpaces;
|
183
|
+
char *title;
|
184
|
+
char *frame;
|
185
|
+
CGDirectDisplayID displayID;
|
186
|
+
unsigned int spaceNumber;
|
187
|
+
};
|
188
|
+
|
189
|
+
/*
|
190
|
+
* Struct containing information about windows.
|
191
|
+
* Contains a pointer to an array of tsapi_window structs.
|
192
|
+
*/
|
193
|
+
struct tsapi_windows {
|
194
|
+
unsigned int windowCount;
|
195
|
+
struct tsapi_window *windows;
|
196
|
+
};
|
197
|
+
|
198
|
+
/*
|
199
|
+
* Return a pointer to a tsapi_windows struct containing information about all the windows
|
200
|
+
* in all spaces.
|
201
|
+
*
|
202
|
+
* The windows are listed in space order for each display, and within each space
|
203
|
+
* the windows are listed front to back, so earlier windows in the array are frontmost.
|
204
|
+
*
|
205
|
+
* You must call tsapi_freeWindowList when you have finished with this.
|
206
|
+
*/
|
207
|
+
struct tsapi_windows *tsapi_windowList();
|
208
|
+
|
209
|
+
/*
|
210
|
+
* Free a previously returned tsapi_spaces struct
|
211
|
+
*/
|
212
|
+
void tsapi_freeWindowList(struct tsapi_windows *windowList);
|
213
|
+
|
214
|
+
/*
|
215
|
+
* Move a window to a different space
|
216
|
+
* The windowId must be one that has been returned in a tsapi_window struct
|
217
|
+
*
|
218
|
+
* Returns true on success, false if the windowID or spaceNumber was invalid
|
219
|
+
*/
|
220
|
+
bool tsapi_moveWindowToSpaceOnDisplay(unsigned int windowID, unsigned int spaceNumber, CGDirectDisplayID displayID);
|
221
|
+
|
222
|
+
/*
|
223
|
+
* Move a space to another position
|
224
|
+
* You cannot move space 1 when displays have separate spaces is turned off.
|
225
|
+
*
|
226
|
+
* Returns true on success, false if the spaceNumber or positionNumber was
|
227
|
+
* invalid
|
228
|
+
*/
|
229
|
+
bool tsapi_moveSpaceToPositionOnDisplay(unsigned int spaceNumber, unsigned int positionNumber, CGDirectDisplayID displayID);
|
230
|
+
|
231
|
+
/*
|
232
|
+
* Add desktops
|
233
|
+
* There can usually be at most 16 desktops, unless desktops have migrated
|
234
|
+
* from another monitor.
|
235
|
+
*
|
236
|
+
* Returns the number of desktops actually added.
|
237
|
+
*/
|
238
|
+
unsigned int tsapi_addDesktopsOnDisplay(unsigned int numberToAdd, CGDirectDisplayID displayID);
|
239
|
+
|
240
|
+
/*
|
241
|
+
* Remove desktops
|
242
|
+
* Removes numberToRemove desktops. The highest numbered desktops are removed.
|
243
|
+
*
|
244
|
+
* Removing a desktop you are currently on will result in TotalSpaces switching to
|
245
|
+
* another dektop.
|
246
|
+
*
|
247
|
+
* Any windows present on a desktop being removed will be moved to one of the
|
248
|
+
* remaining desktops.
|
249
|
+
*
|
250
|
+
* Returns true on success, false if numberToRemove was zero or would result in less
|
251
|
+
* than 1 desktop remaining.
|
252
|
+
*/
|
253
|
+
bool tsapi_removeDesktopsOnDisplay(unsigned int numberToRemove, CGDirectDisplayID displayID);
|
254
|
+
|
255
|
+
#endif
|
256
|
+
|
Binary file
|
data/lib/totalspaces2.rb
ADDED
@@ -0,0 +1,575 @@
|
|
1
|
+
# = TotalSpaces2 - Ruby API bindings for TotalSpaces2 from BinaryAge
|
2
|
+
#
|
3
|
+
# This gem enables you to get information from and to control {TotalSpaces2}[link:http://totalspaces.binaryage.com]
|
4
|
+
#
|
5
|
+
# It is the officially supported way of using the API library libtotalspaces2api, and the required dylib
|
6
|
+
# comes bundled with this gem. This gem uses {Ruby-FFI}[link:https://github.com/ffi/ffi] to call the functions in the dylib.
|
7
|
+
# You'll need a sane ruby and compilation environment to install ruby-ffi - it probably won't install immediately with the
|
8
|
+
# ruby that comes with OSX because none of the compilation tools are present. We use {homebrew}[link:http://mxcl.github.com/homebrew/]
|
9
|
+
# and {rbenv}[link:https://github.com/sstephenson/rbenv/] to manage our ruby scripting environment.
|
10
|
+
#
|
11
|
+
# You may use this gem in various ways. For instance, you could:
|
12
|
+
#
|
13
|
+
# * Display a message or alert when a particular space is moved to
|
14
|
+
#
|
15
|
+
# * Automatically change the name of spaces depending on what apps are in them
|
16
|
+
#
|
17
|
+
# * Record which spaces certain windows are on, and restoring those windows to those spaces when the owning app restarts
|
18
|
+
#
|
19
|
+
# * Trigger moving certain windows between spaces
|
20
|
+
#
|
21
|
+
# API support, and support for this gem starts with TotalSpaces2 v2.1.0. The API is a premium feature,
|
22
|
+
# and will only work with registered versions of TotalSpaces2.
|
23
|
+
#
|
24
|
+
# == Download and installation
|
25
|
+
#
|
26
|
+
# The latest version of the TotalSpaces2 gem can be installed with RubyGems:
|
27
|
+
#
|
28
|
+
# % [sudo] gem install totalspaces2
|
29
|
+
#
|
30
|
+
# Source code can be downloaded on GitHub
|
31
|
+
#
|
32
|
+
# * https://github.com/binaryage/totalspaces2-api
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# == Documentation
|
36
|
+
#
|
37
|
+
# * http://binaryage.github.io/totalspaces2-api/ruby/rdoc/TotalSpaces2.html
|
38
|
+
#
|
39
|
+
# == License
|
40
|
+
#
|
41
|
+
# The TotalSpaces gem is released under the MIT license:
|
42
|
+
#
|
43
|
+
# * http://www.opensource.org/licenses/MIT
|
44
|
+
#
|
45
|
+
# The source code of the dylib is not available at this time.
|
46
|
+
#
|
47
|
+
#
|
48
|
+
# == Support and feature requests
|
49
|
+
#
|
50
|
+
# * http://discuss.binaryage.com
|
51
|
+
#
|
52
|
+
#
|
53
|
+
# == Examples
|
54
|
+
# require 'totalspaces2'
|
55
|
+
#
|
56
|
+
# TotalSpaces2.on_space_change {|from, to, display_id| puts "Moving from space #{from} to space #{to}";}
|
57
|
+
#
|
58
|
+
# TotalSpaces2.move_to_space(1)
|
59
|
+
#
|
60
|
+
# current_space = TotalSpaces2.current_space
|
61
|
+
# puts "Current space number: #{current_space}"
|
62
|
+
# puts "Current space is called: #{TotalSpaces2.name_for_space(current_space)}"
|
63
|
+
#
|
64
|
+
# TotalSpaces2.set_name_for_space(1, "Home")
|
65
|
+
#
|
66
|
+
|
67
|
+
require 'ffi'
|
68
|
+
|
69
|
+
module TSApi #:nodoc:
|
70
|
+
extend FFI::Library
|
71
|
+
ffi_lib File.join(File.dirname(__FILE__), "libtotalspaces2api.dylib")
|
72
|
+
|
73
|
+
attach_function :tsapi_freeString, [:pointer], :void
|
74
|
+
|
75
|
+
attach_function :tsapi_libTotalSpacesVersion, [], :pointer
|
76
|
+
attach_function :tsapi_apiVersion, [], :pointer
|
77
|
+
attach_function :tsapi_totalSpacesVersion, [], :pointer
|
78
|
+
|
79
|
+
attach_function :tsapi_displayList, [], :pointer
|
80
|
+
attach_function :tsapi_freeDisplayList, [:pointer], :void
|
81
|
+
|
82
|
+
attach_function :tsapi_currentSpaceNumberOnDisplay, [:uint], :uint
|
83
|
+
attach_function :tsapi_spaceNameForSpaceNumberOnDisplay, [:uint, :uint], :pointer
|
84
|
+
attach_function :tsapi_numberOfSpacesOnDisplay, [:uint], :uint
|
85
|
+
|
86
|
+
attach_function :tsapi_definedColumnsOnDisplay, [:uint], :uint
|
87
|
+
|
88
|
+
attach_function :tsapi_setDefinedColumnsOnDisplay, [:uint, :uint], :bool
|
89
|
+
|
90
|
+
attach_function :tsapi_moveToSpaceOnDisplay, [:uint, :uint], :bool
|
91
|
+
attach_function :tsapi_setNameForSpaceOnDisplay, [:uint, :string, :uint], :bool
|
92
|
+
|
93
|
+
callback :space_change_function, [:uint, :uint, :uint], :void
|
94
|
+
attach_function :tsapi_setSpaceWillChangeCallback, [:space_change_function], :void
|
95
|
+
attach_function :tsapi_unsetSpaceWillChangeCallback, [], :void
|
96
|
+
|
97
|
+
callback :layout_changed_function, [], :void
|
98
|
+
attach_function :tsapi_setLayoutChangedCallback, [:layout_changed_function], :void
|
99
|
+
attach_function :tsapi_unsetLayoutChangedCallback, [], :void
|
100
|
+
|
101
|
+
attach_function :tsapi_windowList, [], :pointer
|
102
|
+
attach_function :tsapi_freeWindowList, [:pointer], :void
|
103
|
+
|
104
|
+
attach_function :tsapi_moveWindowToSpaceOnDisplay, [:uint, :uint, :uint], :bool
|
105
|
+
|
106
|
+
attach_function :tsapi_moveSpaceToPositionOnDisplay, [:uint, :uint, :uint], :bool
|
107
|
+
|
108
|
+
attach_function :tsapi_addDesktopsOnDisplay, [:uint, :uint], :uint
|
109
|
+
attach_function :tsapi_removeDesktopsOnDisplay, [:uint, :uint], :bool
|
110
|
+
end
|
111
|
+
|
112
|
+
module TotalSpaces2
|
113
|
+
|
114
|
+
MAX_DESKTOPS = 16
|
115
|
+
|
116
|
+
#--
|
117
|
+
# See TSLib.h for the structures returned by the C API
|
118
|
+
#++
|
119
|
+
|
120
|
+
class Display < FFI::Struct #:nodoc:
|
121
|
+
layout :displayID, :uint32,
|
122
|
+
:display_name, :string,
|
123
|
+
:width, :size_t,
|
124
|
+
:height, :size_t
|
125
|
+
end
|
126
|
+
|
127
|
+
class Displays < FFI::Struct #:nodoc:
|
128
|
+
layout :count, :uint,
|
129
|
+
:displays_array, :pointer
|
130
|
+
|
131
|
+
def display_info
|
132
|
+
displays = []
|
133
|
+
displays_array = self[:displays_array]
|
134
|
+
(0...self[:count]).each do |n|
|
135
|
+
display = Display.new(displays_array + n * Display.size)
|
136
|
+
info = {
|
137
|
+
display_id: display[:displayID],
|
138
|
+
display_name: display[:display_name],
|
139
|
+
width: display[:width],
|
140
|
+
height: display[:height]
|
141
|
+
}
|
142
|
+
displays << info
|
143
|
+
end
|
144
|
+
|
145
|
+
displays
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class Windows < FFI::Struct #:nodoc:
|
150
|
+
layout :count, :uint,
|
151
|
+
:windows_array, :pointer
|
152
|
+
end
|
153
|
+
|
154
|
+
class Window < FFI::Struct #:nodoc:
|
155
|
+
layout :app_name, :string,
|
156
|
+
:window_id, :uint,
|
157
|
+
:is_on_all_spaces, :bool,
|
158
|
+
:title, :string,
|
159
|
+
:frame, :string,
|
160
|
+
:display_id, :uint,
|
161
|
+
:space_number, :uint
|
162
|
+
end
|
163
|
+
|
164
|
+
class << self
|
165
|
+
private
|
166
|
+
def string_and_free(cstr_pointer) #:nodoc:
|
167
|
+
str = cstr_pointer.get_string(0)
|
168
|
+
TSApi.tsapi_freeString(cstr_pointer)
|
169
|
+
str
|
170
|
+
end
|
171
|
+
|
172
|
+
public
|
173
|
+
|
174
|
+
# Returns the version of the dylib, a string such as "1.0"
|
175
|
+
# You should be using the same dylib major version number as that returned by the api_version call
|
176
|
+
#
|
177
|
+
# puts "libTotalSpaces2 version: #{TotalSpaces2.lib_total_spaces_version}"
|
178
|
+
#
|
179
|
+
# if TotalSpaces2.lib_total_spaces_version.split('.')[0] != TotalSpaces2.api_version.split('.')[0]
|
180
|
+
# puts "Comms error!"
|
181
|
+
# exit(1)
|
182
|
+
# end
|
183
|
+
#
|
184
|
+
#
|
185
|
+
def lib_total_spaces_version
|
186
|
+
string_and_free(TSApi.tsapi_libTotalSpacesVersion)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns the version of the api present in TotalSpaces2, a string such as "1.0"
|
190
|
+
# You should be using the same dylib version as that returned by the this call
|
191
|
+
#
|
192
|
+
# puts "TotalSpaces2 API version: #{TotalSpaces2.api_version}"
|
193
|
+
#
|
194
|
+
# if TotalSpaces2.lib_total_spaces_version.split('.')[0] != TotalSpaces2.api_version.split('.')[0]
|
195
|
+
# puts "Comms error!"
|
196
|
+
# exit(1)
|
197
|
+
# end
|
198
|
+
#
|
199
|
+
def api_version
|
200
|
+
string_and_free(TSApi.tsapi_apiVersion)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Returns the version of TotalSpaces2 running on the system, a string such as "2.0.12"
|
204
|
+
#
|
205
|
+
# puts "TotalSpaces2 version: #{TotalSpaces2.total_spaces_version}"
|
206
|
+
#
|
207
|
+
def total_spaces_version
|
208
|
+
string_and_free(TSApi.tsapi_totalSpacesVersion)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns an array of hashes with information about attached displays. The ids returned
|
212
|
+
# from this call can be used where a display id is required in the other calls in this library.
|
213
|
+
#
|
214
|
+
# puts "Attached displays: #{TotalSpaces2.display_list}"
|
215
|
+
#
|
216
|
+
# [{:display_id=>69679040, :display_name=>"Color LCD", :width=>1440, :height=>900},
|
217
|
+
# {:display_id=>69514913, :display_name=>"LED Cinema Display", :width=>2560, :height=>1440}]
|
218
|
+
#
|
219
|
+
def display_list
|
220
|
+
list = TSApi.tsapi_displayList
|
221
|
+
displays = Displays.new(list)
|
222
|
+
result = displays.null? ? [] : displays.display_info
|
223
|
+
TSApi.tsapi_freeDisplayList(list)
|
224
|
+
result
|
225
|
+
end
|
226
|
+
|
227
|
+
# Returns information about the main display.
|
228
|
+
# Methods that do not take a display id always operate on this display.
|
229
|
+
#
|
230
|
+
# puts "Main display id: #{TotalSpaces2.main_display_id}"
|
231
|
+
#
|
232
|
+
# {:display_id=>69679040, :display_name=>"Color LCD", :width=>1440, :height=>900}
|
233
|
+
#
|
234
|
+
def main_display
|
235
|
+
self.display_list[0]
|
236
|
+
end
|
237
|
+
|
238
|
+
# Returns the number of the current space on the main display. Numbering starts at 1.
|
239
|
+
#
|
240
|
+
# puts "Current space number: #{TotalSpaces2.current_space}"
|
241
|
+
#
|
242
|
+
def current_space
|
243
|
+
TSApi.tsapi_currentSpaceNumberOnDisplay(0)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Returns the number of the current space on the given display.
|
247
|
+
# Space numbering starts at 1
|
248
|
+
#
|
249
|
+
# display_id = TotalSpaces2.displays[0]
|
250
|
+
# puts "Current space number: #{TotalSpaces2.current_space_on_display(display_id)}"
|
251
|
+
#
|
252
|
+
def current_space_on_display(display_id)
|
253
|
+
TSApi.tsapi_currentSpaceNumberOnDisplay(display_id)
|
254
|
+
end
|
255
|
+
|
256
|
+
# Returns the name for a space on the main display. The returned string will be empty
|
257
|
+
# if the space number is not valid
|
258
|
+
#
|
259
|
+
# current_space = TotalSpaces2.current_space
|
260
|
+
# puts "Current space is called: #{TotalSpaces2.name_for_space(current_space)}"
|
261
|
+
#
|
262
|
+
def name_for_space(space_number)
|
263
|
+
name = string_and_free(TSApi.tsapi_spaceNameForSpaceNumberOnDisplay(space_number, 0))
|
264
|
+
name.force_encoding("UTF-8")
|
265
|
+
end
|
266
|
+
|
267
|
+
# Returns the name for a space. The returned string will be empty if the space number is
|
268
|
+
# not valid
|
269
|
+
#
|
270
|
+
# current_space = TotalSpaces2.current_space
|
271
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
272
|
+
# puts "Current space is called: #{TotalSpaces2.name_for_space_on_display(current_space, display_id)}"
|
273
|
+
#
|
274
|
+
def name_for_space_on_display(space_number, display_id)
|
275
|
+
name = string_and_free(TSApi.tsapi_spaceNameForSpaceNumberOnDisplay(space_number, display_id))
|
276
|
+
name.force_encoding("UTF-8")
|
277
|
+
end
|
278
|
+
|
279
|
+
# Returns the total number of spaces including fullscreens, dashboard (if it's a space).
|
280
|
+
#
|
281
|
+
# puts "Total number of spaces: #{TotalSpaces2.number_of_spaces}"
|
282
|
+
#
|
283
|
+
def number_of_spaces
|
284
|
+
TSApi.tsapi_numberOfSpacesOnDisplay(0)
|
285
|
+
end
|
286
|
+
|
287
|
+
# Returns the total number of spaces including fullscreens, dashboard (if it's a space).
|
288
|
+
#
|
289
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
290
|
+
# puts "Total number of spaces: #{TotalSpaces2.number_of_spaces_on_display(display_id)}"
|
291
|
+
#
|
292
|
+
def number_of_spaces_on_display(display_id)
|
293
|
+
TSApi.tsapi_numberOfSpacesOnDisplay(display_id)
|
294
|
+
end
|
295
|
+
|
296
|
+
# Returns the number of columns defined in TotalSpaces2 for the main display
|
297
|
+
#
|
298
|
+
# puts "Number of columns: #{TotalSpaces2.grid_columns}"
|
299
|
+
#
|
300
|
+
def grid_columns
|
301
|
+
TSApi.tsapi_definedColumnsOnDisplay(0)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Returns the number of columns defined in TotalSpaces2
|
305
|
+
#
|
306
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
307
|
+
# puts "Number of columns: #{TotalSpaces2.grid_columns_on_display(display_id)}"
|
308
|
+
#
|
309
|
+
def grid_columns_on_display(display_id)
|
310
|
+
TSApi.tsapi_definedColumnsOnDisplay(display_id)
|
311
|
+
end
|
312
|
+
|
313
|
+
# Sets the number of columns defined in TotalSpaces2 for the main display.
|
314
|
+
#
|
315
|
+
# This does not change the actual number of desktops present, you should
|
316
|
+
# call add_desktops or remove_desktops as appropriate after changing the number
|
317
|
+
# of columns.
|
318
|
+
#
|
319
|
+
# TotalSpaces2.set_grid_columns(3)
|
320
|
+
#
|
321
|
+
def set_grid_columns(columns)
|
322
|
+
TSApi.tsapi_setDefinedColumnsOnDisplay(columns, 0)
|
323
|
+
end
|
324
|
+
|
325
|
+
# Sets the number of columns defined in TotalSpaces2.
|
326
|
+
#
|
327
|
+
# This does not change the actual number of desktops present, you should
|
328
|
+
# call add_desktops_on_display or remove_desktops_on_display as appropriate
|
329
|
+
# after changing the number of columns.
|
330
|
+
#
|
331
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
332
|
+
# TotalSpaces2.set_grid_columns_on_display(3, display_id)
|
333
|
+
#
|
334
|
+
def set_grid_columns_on_display(columns, display_id)
|
335
|
+
TSApi.tsapi_setDefinedColumnsOnDisplay(columns, display_id)
|
336
|
+
end
|
337
|
+
|
338
|
+
# Command TotalSpaces2 to switch to the given space number on the main display.
|
339
|
+
# Returns false if the space number was invalid.
|
340
|
+
# The on_space_change notification will be sent.
|
341
|
+
#
|
342
|
+
# TotalSpaces2.move_to_space(1)
|
343
|
+
#
|
344
|
+
def move_to_space(space_number)
|
345
|
+
TSApi.tsapi_moveToSpaceOnDisplay(space_number, 0)
|
346
|
+
end
|
347
|
+
|
348
|
+
# Command TotalSpaces2 to switch to the given space number.
|
349
|
+
# Returns false if the space number was invalid.
|
350
|
+
# The on_space_change notification will be sent.
|
351
|
+
#
|
352
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
353
|
+
# TotalSpaces2.move_to_space_on_Display(1, display_id)
|
354
|
+
#
|
355
|
+
def move_to_space_on_display(space_number, display_id)
|
356
|
+
TSApi.tsapi_moveToSpaceOnDisplay(space_number, display_id)
|
357
|
+
end
|
358
|
+
|
359
|
+
# Set the name for a space on the main display.
|
360
|
+
# Note that using this command will cause a layout change notification to be sent
|
361
|
+
# if the new name was different from that previously set.
|
362
|
+
# The maximum length for a name is 255 bytes.
|
363
|
+
#
|
364
|
+
# TotalSpaces2.set_name_for_space(1, "Home")
|
365
|
+
#
|
366
|
+
def set_name_for_space(space_number, name)
|
367
|
+
TSApi.tsapi_setNameForSpaceOnDisplay(space_number, name, 0)
|
368
|
+
end
|
369
|
+
|
370
|
+
# Set the name for a space.
|
371
|
+
# Note that using this command will cause a layout change notification to be sent
|
372
|
+
# if the new name was different from that previously set.
|
373
|
+
# The maximum length for a name is 255 bytes.
|
374
|
+
#
|
375
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
376
|
+
# TotalSpaces2.set_name_for_space_on_display(1, "Home", display_id)
|
377
|
+
#
|
378
|
+
def set_name_for_space_on_display(space_number, name, display_id)
|
379
|
+
TSApi.tsapi_setNameForSpaceOnDisplay(space_number, name, display_id)
|
380
|
+
end
|
381
|
+
|
382
|
+
# Register for notifications on space change.
|
383
|
+
# The given block will be called whenever you move from one space to another. The arguments are
|
384
|
+
# the space number you moved from, and the one you are moving to.
|
385
|
+
#
|
386
|
+
# TotalSpaces2.on_space_change {|from, to, displayID| puts "Moving from space #{from} to space #{to}"}
|
387
|
+
#
|
388
|
+
# sleep
|
389
|
+
#
|
390
|
+
# There can only be one block registered at any time, the most recently registered one will
|
391
|
+
# be called.
|
392
|
+
# This callback is called just before the space actually changes - current_space will still
|
393
|
+
# report the from space.
|
394
|
+
#
|
395
|
+
def on_space_change(&block)
|
396
|
+
$tsapi_on_space_change_block = block # prevent GC
|
397
|
+
TSApi.tsapi_setSpaceWillChangeCallback(block)
|
398
|
+
end
|
399
|
+
|
400
|
+
# Cancel the on_space_change notification.
|
401
|
+
#
|
402
|
+
def cancel_on_space_change
|
403
|
+
$tsapi_on_space_change_block = nil
|
404
|
+
TSApi.tsapi_unsetSpaceWillChangeCallback
|
405
|
+
end
|
406
|
+
|
407
|
+
# Register for notifications on layout change.
|
408
|
+
# The given block will be called whenever the layout changes - this could be due to making an app
|
409
|
+
# fullscreen, changing a space name, or changing the layout of the TotalSpaces2 grid. There are no
|
410
|
+
# arguments passed to the block.
|
411
|
+
#
|
412
|
+
#
|
413
|
+
# TotalSpaces.on_layout_change {puts "Spaces changed"}
|
414
|
+
#
|
415
|
+
# sleep
|
416
|
+
#
|
417
|
+
# When you get a notification from this method, you should re-fetch any information about the spaces
|
418
|
+
# that you may be storing.
|
419
|
+
#
|
420
|
+
# There can only be one block registered at any time, the most recently registered one will
|
421
|
+
# be called.
|
422
|
+
#
|
423
|
+
def on_layout_change(&block)
|
424
|
+
$tsapi_on_layout_change_block = block # prevent GC
|
425
|
+
TSApi.tsapi_setLayoutChangedCallback(block)
|
426
|
+
end
|
427
|
+
|
428
|
+
# Cancel the layout change notification
|
429
|
+
#
|
430
|
+
def cancel_on_layout_change
|
431
|
+
$tsapi_on_layout_change_block = nil
|
432
|
+
TSApi.tsapi_unsetLayoutChangedCallback
|
433
|
+
end
|
434
|
+
|
435
|
+
# Get a list of all the windows on your mac
|
436
|
+
# It returns an array containing a hash for each window.
|
437
|
+
# The hash contains the display id (key :display_id) and space number (key :space_number)
|
438
|
+
# and details for each window.
|
439
|
+
# The windows are in front to back order within each space.
|
440
|
+
# Each window hash also contains a window_id, title, frame, app_name and is_on_all_spaces flag
|
441
|
+
#
|
442
|
+
# The below example would move the frontmost window to the next space to the right.
|
443
|
+
#
|
444
|
+
# windows = TotalSpaces2.window_list
|
445
|
+
# current_space = TotalSpaces2.current_space
|
446
|
+
# main_display_id = TotalSpaces2.main_display[:display_id]
|
447
|
+
# if !windows.empty?
|
448
|
+
# current_space_windows = windows.select {|window| window[:display_id] == main_display_id
|
449
|
+
# && window[:space_number] == current_space}
|
450
|
+
# front_window = current_space_windows[0]
|
451
|
+
# TotalSpaces2.move_window_to_space(front_window[:window_id], TotalSpaces.current_space + 1)
|
452
|
+
# end
|
453
|
+
#
|
454
|
+
def window_list
|
455
|
+
result = []
|
456
|
+
list = TSApi.tsapi_windowList
|
457
|
+
main_array = Windows.new(list)
|
458
|
+
|
459
|
+
(0...main_array[:count]).each do |n|
|
460
|
+
window = Window.new(main_array[:windows_array] + n * Window.size)
|
461
|
+
window_hash = {}
|
462
|
+
window_hash[:window_id] = window[:window_id]
|
463
|
+
window_hash[:title] = window[:title].dup.force_encoding("UTF-8")
|
464
|
+
window_hash[:frame] = window[:frame].dup.force_encoding("UTF-8")
|
465
|
+
window_hash[:is_on_all_spaces] = window[:is_on_all_spaces]
|
466
|
+
window_hash[:app_name] = window[:app_name].dup.force_encoding("UTF-8")
|
467
|
+
window_hash[:display_id] = window[:display_id]
|
468
|
+
window_hash[:space_number] = window[:space_number]
|
469
|
+
result << window_hash
|
470
|
+
end
|
471
|
+
|
472
|
+
TSApi.tsapi_freeWindowList(list)
|
473
|
+
|
474
|
+
result
|
475
|
+
end
|
476
|
+
|
477
|
+
# Move a window to a given space
|
478
|
+
# The window_id parameter must be fetched using window_list.
|
479
|
+
# Returns false if the space_number or window_id is invalid.
|
480
|
+
#
|
481
|
+
def move_window_to_space(window_id, space_number)
|
482
|
+
TSApi.tsapi_moveWindowToSpaceOnDisplay(window_id, space_number, 0)
|
483
|
+
end
|
484
|
+
|
485
|
+
# Move a window to a given space on the main display
|
486
|
+
# The window_id parameter must be fetched using window_list.
|
487
|
+
# Returns false if the space_number or window_id is invalid.
|
488
|
+
#
|
489
|
+
def move_window_to_space_on_display(window_id, space_number, display_id)
|
490
|
+
TSApi.tsapi_moveWindowToSpaceOnDisplay(window_id, space_number, display_id)
|
491
|
+
end
|
492
|
+
|
493
|
+
# Move space to a new position in the grid on the main display.
|
494
|
+
#
|
495
|
+
# Returns false if the space_number or position_number is not valid.
|
496
|
+
#
|
497
|
+
# TotalSpaces2.move_space_to_position(4, 2)
|
498
|
+
#
|
499
|
+
def move_space_to_position(space_number, position_number)
|
500
|
+
TSApi.tsapi_moveSpaceToPositionOnDisplay(space_number, position_number)
|
501
|
+
end
|
502
|
+
|
503
|
+
# Move space to a new position in the grid. Spaces can only be moved
|
504
|
+
# within their own display.
|
505
|
+
#
|
506
|
+
# Returns false if the space_number or position_number is not valid.
|
507
|
+
#
|
508
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
509
|
+
# TotalSpaces2.move_space_to_position_on_display(4, 2, display_id)
|
510
|
+
#
|
511
|
+
def move_space_to_position_on_display(space_number, position_number, display_id)
|
512
|
+
TSApi.tsapi_moveSpaceToPositionOnDisplay(space_number, position_number, display_id)
|
513
|
+
end
|
514
|
+
|
515
|
+
# Add desktops
|
516
|
+
# There can be at most 16 desktops unless the display has collected some when
|
517
|
+
# a secondary display has been unplugged.
|
518
|
+
# Returns true on success, false if number_to_add was zero, or would result
|
519
|
+
# in more than 16 desktops.
|
520
|
+
# The on_layout_change notification will be sent if a changed was made.
|
521
|
+
#
|
522
|
+
# TotalSpaces2.add_desktops(1)
|
523
|
+
#
|
524
|
+
def add_desktops(number_to_add)
|
525
|
+
TSApi.tsapi_addDesktopsOnDisplay(number_to_add, 0)
|
526
|
+
end
|
527
|
+
|
528
|
+
# Add desktops
|
529
|
+
# There can be at most 16 desktops unless the display has collected some when
|
530
|
+
# a secondary display has been unplugged.
|
531
|
+
# Returns true on success, false if number_to_add was zero, or would result
|
532
|
+
# in more than 16 desktops.
|
533
|
+
# The on_layout_change notification will be sent if a changed was made.
|
534
|
+
#
|
535
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
536
|
+
# TotalSpaces2.add_desktops_on_display(1, display_id)
|
537
|
+
#
|
538
|
+
def add_desktops_on_display(number_to_add, display_id)
|
539
|
+
TSApi.tsapi_addDesktopsOnDisplay(number_to_add, display_id)
|
540
|
+
end
|
541
|
+
|
542
|
+
# Remove desktops
|
543
|
+
# The highest numbered desktops are removed.
|
544
|
+
# Removing a desktop you are currently on will result in TotalSpaces2 switching to
|
545
|
+
# another dektop.
|
546
|
+
# Any windows present on a desktop being removed will be moved to one of the
|
547
|
+
# remaining desktops.
|
548
|
+
# Returns true on success, false if number_to_remove was zero or would result in less
|
549
|
+
# than 1 desktop remaining.
|
550
|
+
# The on_layout_change notification will be sent if a change was made.
|
551
|
+
#
|
552
|
+
# TotalSpaces2.remove_desktops(1)
|
553
|
+
#
|
554
|
+
def remove_desktops(number_to_remove)
|
555
|
+
TSApi.tsapi_removeDesktopsOnDisplay(number_to_remove, 0)
|
556
|
+
end
|
557
|
+
|
558
|
+
# Remove desktops
|
559
|
+
# The highest numbered desktops are removed.
|
560
|
+
# Removing a desktop you are currently on will result in TotalSpaces2 switching to
|
561
|
+
# another dektop.
|
562
|
+
# Any windows present on a desktop being removed will be moved to one of the
|
563
|
+
# remaining desktops.
|
564
|
+
# Returns true on success, false if number_to_remove was zero or would result in less
|
565
|
+
# than 1 desktop remaining.
|
566
|
+
# The on_layout_change notification will be sent if a change was made.
|
567
|
+
#
|
568
|
+
# display_id = TotalSpaces2.main_display[:display_id]
|
569
|
+
# TotalSpaces2.remove_desktops_on_display(1, display_id)
|
570
|
+
#
|
571
|
+
def remove_desktops_on_display(number_to_remove, display_id)
|
572
|
+
TSApi.tsapi_removeDesktopsOnDisplay(number_to_remove, display_id)
|
573
|
+
end
|
574
|
+
end
|
575
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: totalspaces2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '2.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Sykes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.11
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.11
|
27
|
+
description: This allows you to control the TotalSpaces2 desktop manager for mac from
|
28
|
+
ruby.
|
29
|
+
email: stephen@binaryage.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.rdoc
|
35
|
+
- MIT_LICENCE
|
36
|
+
- lib/totalspaces2.rb
|
37
|
+
- lib/libtotalspaces2api.dylib
|
38
|
+
- lib/TSLib.h
|
39
|
+
homepage: https://github.com/binaryage/totalspaces2-api/tree/master/ruby
|
40
|
+
licenses: []
|
41
|
+
metadata: {}
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.0.3
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: TotalSpaces2 control from ruby
|
63
|
+
test_files: []
|