totalspaces 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -0,0 +1,49 @@
1
+ = TotalSpaces - Ruby API bindings for TotalSpaces from BinaryAge
2
+
3
+ == 2013-02 At present this is pre-release, there is no public version of TotalSpaces containing the API.
4
+
5
+ This gem enables you to get information from and to control {TotalSpaces}[link:http://totalspaces.binaryage.com]
6
+
7
+ It is the officially supported way of using the API library libtotalspacesapi, 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
+
10
+ You may use this gem in various ways. For instance, you could:
11
+
12
+ * Display a message or alert when a particular space is moved to
13
+
14
+ * Automatically change the name of spaces depending on what apps are in them
15
+
16
+ * Record which spaces certain windows are on, and restoring those windows to those spaces when the owning app restarts
17
+
18
+ * Trigger moving certain windows between spaces
19
+
20
+ API support, and support for this gem starts with TotalSpaces v1.1.4. The API is a premium feature,
21
+ and will only work with registered versions of TotalSpaces.
22
+
23
+ == Download and installation
24
+
25
+ The latest version of the TotalSpaces gem can be installed with RubyGems:
26
+
27
+ % [sudo] gem install totalspaces
28
+
29
+ Source code can be downloaded on GitHub
30
+
31
+ * https://github.com/binaryage/totalspaces-api
32
+
33
+
34
+ == Documentation
35
+
36
+ * In progress
37
+
38
+ == License
39
+
40
+ The TotalSpaces gem is released under the MIT license:
41
+
42
+ * http://www.opensource.org/licenses/MIT
43
+
44
+ The source code of the dylib is not available at this time.
45
+
46
+
47
+ == Support and feature requests
48
+
49
+ * http://support.binaryage.com
@@ -0,0 +1,206 @@
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
+ /*
17
+ * In case of comm error, all the functions apart from tsapi_libTotalSpacesVersion() will
18
+ * return an empty string, zero, false or a pointer to a struct containing zero spaces (in
19
+ * the case of tsapi_windowList).
20
+ * It is recommended to check that comms to TotalSpaces are working by, for instance,
21
+ * checking that tsapi_numberOfSpaces() returns a number greater than zero when you initialize
22
+ * your app.
23
+ */
24
+
25
+ /*
26
+ * The version of the API present in TotalSpaces.app
27
+ *
28
+ * You must call tsapi_freeString when you have finished with the returned string.
29
+ */
30
+ const char *tsapi_apiVersion();
31
+
32
+ /*
33
+ * The version number of TotalSpaces itself
34
+ *
35
+ * You must call tsapi_freeString when you have finished with the returned string.
36
+ */
37
+ const char *tsapi_totalSpacesVersion();
38
+
39
+ /*
40
+ * The version of the API dylib. This should match the string returned
41
+ * by tsapi_apiVersion()
42
+ *
43
+ * You must call tsapi_freeString when you have finished with the returned string.
44
+ */
45
+ const char *tsapi_libTotalSpacesVersion();
46
+
47
+ /*
48
+ * The number of the current space
49
+ *
50
+ * If the current space is the dashboard, 0 is returned.
51
+ */
52
+ unsigned int tsapi_currentSpaceNumber();
53
+
54
+ /*
55
+ * The name for the given space number
56
+ *
57
+ * You must call tsapi_freeString when you have finished with the returned string.
58
+ */
59
+ const char *tsapi_spaceNameForSpaceNumber(unsigned int spaceNumber);
60
+
61
+ /*
62
+ * The total number of spaces
63
+ * This includes the dashboard if you have it set as a space, and any
64
+ * fullscreen apps
65
+ */
66
+ unsigned int tsapi_numberOfSpaces();
67
+
68
+ /*
69
+ * The number of fullscreen apps
70
+ */
71
+ unsigned int tsapi_numberOfFullScreens();
72
+
73
+ /*
74
+ * The number of desktops / normal spaces
75
+ */
76
+ unsigned int tsapi_numberOfDesktops();
77
+
78
+ /*
79
+ * The number of fullscreen apps that are allowed to be present
80
+ * in the grid, defined in advanced preferences
81
+ */
82
+ unsigned int tsapi_numberOfFullScreensInGrid();
83
+
84
+ /*
85
+ * Is the dashboard set to be a space in Mission Control preferences
86
+ */
87
+ bool tsapi_dashboardIsASpace();
88
+
89
+ /*
90
+ * The number of rows defined in TotalSpaces layout preferences
91
+ */
92
+ unsigned int tsapi_definedRows();
93
+
94
+ /*
95
+ * The number of columns defined in TotalSpaces layout preferences
96
+ */
97
+ unsigned int tsapi_definedColumns();
98
+
99
+ /*
100
+ * Call this to free strings returned by the TotalSpaces API
101
+ */
102
+ void tsapi_freeString(char *str);
103
+
104
+ /*
105
+ * Switch the display to the given space
106
+ * Returns false if the space number is invalid
107
+ */
108
+ bool tsapi_moveToSpace(unsigned int spaceNumber);
109
+
110
+ /*
111
+ * Set the name of a space
112
+ * The maximum length is 255 bytes. The name should be in UTF-8
113
+ * Returns true on success, false if the name was too long or the space number was invalid
114
+ */
115
+ bool tsapi_setNameForSpace(unsigned int spaceNumber, char *name);
116
+
117
+ /*
118
+ * Type for space change callback
119
+ */
120
+ typedef void (*space_change_callback_t)(unsigned int fromSpaceNumber, unsigned int toSpaceNumber);
121
+
122
+ /*
123
+ * Set the function that will be called when the visible space changes
124
+ * There is only one callback per process, registering a new callback will supercede any previous one
125
+ */
126
+ void tsapi_setSpaceWillChangeCallback(space_change_callback_t callback);
127
+
128
+ /*
129
+ * Cancel space change callbacks
130
+ */
131
+ void tsapi_unsetSpaceWillChangeCallback();
132
+
133
+ /*
134
+ * Type for layout change callback
135
+ */
136
+ typedef void (*space_layout_changed_callback_t)(void);
137
+
138
+ /*
139
+ * Set the function that will be called when the layout changes
140
+ * This could be any change - for instance adding or removing a fullscreen, changing the name of a space,
141
+ * or a change of rows or columns.
142
+ * It indicates that you should re-request any information you are holding on the spaces
143
+ * There is only one callback per process, registering a new callback will supercede any previous one
144
+ */
145
+ void tsapi_setLayoutChangedCallback(space_layout_changed_callback_t callback);
146
+
147
+ /*
148
+ * Cancel layout change callbacks
149
+ */
150
+ void tsapi_unsetLayoutChangedCallback();
151
+
152
+ /*
153
+ * Struct containing information about a window
154
+ */
155
+ struct tsapi_window {
156
+ char *appName;
157
+ unsigned int windowId;
158
+ bool isOnAllSpaces;
159
+ char *title;
160
+ char *frame;
161
+ };
162
+
163
+ /*
164
+ * Struct containing information about a space
165
+ * Contains a pointer to an array of tsapi_window structs
166
+ */
167
+ struct tsapi_space {
168
+ unsigned int spaceNumber;
169
+ unsigned int windowCount;
170
+ struct tsapi_window *windows;
171
+ };
172
+
173
+ /*
174
+ * Struct containing the count of spaces and a pointer to an
175
+ * array of tsapi_space structs
176
+ */
177
+ struct tsapi_spaces {
178
+ unsigned int spacesCount;
179
+ struct tsapi_space *spaces;
180
+ };
181
+
182
+ /*
183
+ * Return a pointer to a tsapi_spaces struct containing information about all the windows
184
+ * in all spaces
185
+ *
186
+ * The windows are listed front to back, so the first widow in the array is the frontmost
187
+ *
188
+ * You must call tsapi_freeWindowList when you have finished with this
189
+ */
190
+ struct tsapi_spaces *tsapi_windowList();
191
+
192
+ /*
193
+ * Free a previously returned spaceWindowsArray struct
194
+ */
195
+ void tsapi_freeWindowList(struct tsapi_spaces *windowList);
196
+
197
+ /*
198
+ * Move a window to a different space
199
+ * The windowId must be one that has been returned in a tsapi_window struct
200
+ *
201
+ * Returns true on success, false if the windowId or spaceNumber was invalid
202
+ */
203
+ bool tsapi_moveWindowToSpace(unsigned int windowId, unsigned int spaceNumber);
204
+
205
+ #endif
206
+
@@ -0,0 +1,318 @@
1
+ # TotalSpaces - control TotalSpaces from Ruby
2
+ # This gem provides a number of ways to control TotalSpaces. It is intended to be used
3
+ # to add functionality to TotalSpaces, or to use your spaces and desktops in
4
+ # creative ways.
5
+ #
6
+ # === Examples
7
+ # require 'totalspaces'
8
+ #
9
+ # TotalSpaces.on_space_change {|from, to| puts "Moving from space #{from} to space #{to}";}
10
+ #
11
+ # TotalSpaces.move_to_space(1)
12
+ #
13
+ # current_space = TotalSpaces.current_space
14
+ # puts "Current space number: #{current_space}"
15
+ # puts "Current space is called: #{TotalSpaces.name_for_space(current_space)}"
16
+ #
17
+ # TotalSpaces.set_name_for_space(1, "Home")
18
+ #
19
+
20
+ require 'ffi'
21
+
22
+ module TSApi #:nodoc:
23
+ extend FFI::Library
24
+ ffi_lib File.join(File.dirname(__FILE__), "libtotalspacesapi.dylib")
25
+
26
+ attach_function :tsapi_freeString, [:pointer], :void
27
+
28
+ attach_function :tsapi_libTotalSpacesVersion, [], :pointer
29
+ attach_function :tsapi_apiVersion, [], :pointer
30
+ attach_function :tsapi_totalSpacesVersion, [], :pointer
31
+
32
+ attach_function :tsapi_currentSpaceNumber, [], :uint
33
+ attach_function :tsapi_spaceNameForSpaceNumber, [:uint], :pointer
34
+ attach_function :tsapi_numberOfSpaces, [], :uint
35
+ attach_function :tsapi_numberOfFullScreens, [], :uint
36
+ attach_function :tsapi_numberOfFullScreensInGrid, [], :uint
37
+ attach_function :tsapi_numberOfDesktops, [], :uint
38
+ attach_function :tsapi_dashboardIsASpace, [], :bool
39
+ attach_function :tsapi_definedRows, [], :uint
40
+ attach_function :tsapi_definedColumns, [], :uint
41
+
42
+ attach_function :tsapi_moveToSpace, [:uint], :bool
43
+ attach_function :tsapi_setNameForSpace, [:uint, :string], :bool
44
+
45
+ callback :space_change_function, [:uint, :uint], :void
46
+ attach_function :tsapi_setSpaceWillChangeCallback, [:space_change_function], :void
47
+ attach_function :tsapi_unsetSpaceWillChangeCallback, [], :void
48
+
49
+ callback :layout_changed_function, [], :void
50
+ attach_function :tsapi_setLayoutChangedCallback, [:layout_changed_function], :void
51
+ attach_function :tsapi_unsetLayoutChangedCallback, [], :void
52
+
53
+ attach_function :tsapi_windowList, [], :pointer
54
+ attach_function :tsapi_freeWindowList, [:pointer], :void
55
+
56
+ attach_function :tsapi_moveWindowToSpace, [:uint, :uint], :bool
57
+ end
58
+
59
+ module TotalSpaces
60
+
61
+ #--
62
+ # See tslib.h for the structures returned by the C API
63
+ #++
64
+
65
+ class Spaces < FFI::Struct #:nodoc:
66
+ layout :count, :uint,
67
+ :windows_arrays, :pointer
68
+ end
69
+
70
+ class Space < FFI::Struct #:nodoc:
71
+ layout :space_number, :uint,
72
+ :count, :uint,
73
+ :windows_array, :pointer
74
+ end
75
+
76
+ class Window < FFI::Struct #:nodoc:
77
+ layout :app_name, :string,
78
+ :window_id, :uint,
79
+ :is_on_all_spaces, :bool,
80
+ :title, :string,
81
+ :frame, :string
82
+ end
83
+
84
+ class << self
85
+ private
86
+ def string_and_free(cstr_pointer) #:nodoc:
87
+ str = cstr_pointer.get_string(0)
88
+ TSApi.tsapi_freeString(cstr_pointer)
89
+ str
90
+ end
91
+
92
+ public
93
+
94
+ # Returns the version of the dylib, a string such as "1.0"
95
+ # You should be using the same dylib version as that returned by the api_version call
96
+ #
97
+ # puts "libTotalSpaces version: #{TotalSpaces.lib_total_spaces_version}"
98
+ #
99
+ def lib_total_spaces_version
100
+ string_and_free(TSApi.tsapi_libTotalSpacesVersion)
101
+ end
102
+
103
+ # Returns the version of the api present in TotalSpaces, a string such as "1.0"
104
+ # You should be using the same dylib version as that returned by the this call
105
+ #
106
+ # puts "TotalSpaces API version: #{TotalSpaces.api_version}"
107
+ #
108
+ def api_version
109
+ string_and_free(TSApi.tsapi_apiVersion)
110
+ end
111
+
112
+ # Returns the version of TotalSpaces running on the system, a string such as "1.1.4"
113
+ #
114
+ # puts "TotalSpaces version: #{TotalSpaces.total_spaces_version}"
115
+ #
116
+ def total_spaces_version
117
+ string_and_free(TSApi.tsapi_totalSpacesVersion)
118
+ end
119
+
120
+ # Returns the number of the current space. Numbering starts at 1, except if you have
121
+ # the Dashboard enabled as a space, in which case the Dashboard counts as space 0
122
+ #
123
+ # puts "Current space number: #{TotalSpaces.current_space}"
124
+ #
125
+ def current_space
126
+ TSApi.tsapi_currentSpaceNumber
127
+ end
128
+
129
+ # Returns the name for a space. The returned string will be empty if the space number is
130
+ # not valid
131
+ #
132
+ # current_space = TotalSpaces.current_space
133
+ # puts "Current space is called: #{TotalSpaces.name_for_space(current_space)}"
134
+ #
135
+ def name_for_space(space_number)
136
+ name = string_and_free(TSApi.tsapi_spaceNameForSpaceNumber(space_number))
137
+ name.force_encoding("UTF-8")
138
+ end
139
+
140
+ # Returns the total number of spaces including fullscreens, dashboard (if it's a space),
141
+ # and spaces that are unused in the grid
142
+ #
143
+ # puts "Total number of spaces: #{TotalSpaces.number_of_spaces}"
144
+ #
145
+ def number_of_spaces
146
+ TSApi.tsapi_numberOfSpaces
147
+ end
148
+
149
+ # Returns the number of fullscreen apps present
150
+ #
151
+ # puts "Number of fullscreens: #{TotalSpaces.number_of_fullscreens}"
152
+ #
153
+ def number_of_fullscreens
154
+ TSApi.tsapi_numberOfFullScreens
155
+ end
156
+
157
+ # Returns the number of fullscreen apps tht are defined in the grid - this can be defined
158
+ # in Advanced preferences in TotalSpaces.
159
+ # The return value does not depend on how many fullscreens actually exist in the grid - the
160
+ # value is the definition only, there could be fewer than this actually present.
161
+ #
162
+ # puts "Number of fullscreens in the grid: #{TotalSpaces.number_of_fullscreens_in_grid}"
163
+ #
164
+ def number_of_fullscreens_in_grid
165
+ TSApi.tsapi_numberOfFullScreensInGrid
166
+ end
167
+
168
+ # Returns the number of desktops that are present in the system. This may be a bigger number
169
+ # that the rows x columns in the grid if more desktops have been created in Mission Control.
170
+ #
171
+ # puts "Number of desktops: #{TotalSpaces.number_of_desktops}"
172
+ #
173
+ def number_of_desktops
174
+ TSApi.tsapi_numberOfDesktops
175
+ end
176
+
177
+ # Returns true if the dashboard is configured to appear as a space in Mission Control preferences.
178
+ #
179
+ # puts "Dashboard is a space: #{TotalSpaces.dashboard_is_a_space?}"
180
+ #
181
+ def dashboard_is_a_space?
182
+ TSApi.tsapi_dashboardIsASpace
183
+ end
184
+
185
+ # Returns the number of rows defined in TotalSpaces
186
+ #
187
+ # puts "Number of rows: #{TotalSpaces.grid_rows}"
188
+ #
189
+ def grid_rows
190
+ TSApi.tsapi_definedRows
191
+ end
192
+
193
+ # Returns the number of columns defined in TotalSpaces
194
+ #
195
+ # puts "Number of columns: #{TotalSpaces.grid_columns}"
196
+ #
197
+ def grid_columns
198
+ TSApi.tsapi_definedColumns
199
+ end
200
+
201
+ # Command TotalSpaces to switch to the given space number
202
+ # Returns false if the space number was invalid
203
+ # The on_space_change notification will be sent
204
+ #
205
+ # TotalSpaces.move_to_space(1)
206
+ #
207
+ def move_to_space(space_number)
208
+ TSApi.tsapi_moveToSpace(space_number)
209
+ end
210
+
211
+ # Set the name for a space
212
+ # Note that using this command will cause a layout notification to be sent
213
+ # if the new name was different from that previously set
214
+ # The maximum length for a name is 255 bytes
215
+ #
216
+ # TotalSpaces.set_name_for_space(1, "Home")
217
+ #
218
+ def set_name_for_space(space_number, name)
219
+ TSApi.tsapi_setNameForSpace(space_number, name)
220
+ end
221
+
222
+ # Register for notifications on space change
223
+ # The given block will be called whenever you move from one space to another. The arguments are
224
+ # the space number you moved from, and the one you are moving to
225
+ #
226
+ # TotalSpaces.on_space_change {|from, to| puts "Moving from space #{from} to space #{to}";}
227
+ #
228
+ # There can only be one block registered at any time, the most recently registered one will
229
+ # be called.
230
+ #
231
+ def on_space_change(&block)
232
+ $tsapi_on_space_change_block = block # prevent CG
233
+ TSApi.tsapi_setSpaceWillChangeCallback(block)
234
+ end
235
+
236
+ # Cancel the on_space_change notification
237
+ #
238
+ def cancel_on_space_change
239
+ $tsapi_on_space_change_block = nil
240
+ TSApi.tsapi_unsetSpaceWillChangeCallback
241
+ end
242
+
243
+ # Register for notifications on layout change
244
+ # The given block will be called whenever the layout changes - this could be due to making an app
245
+ # fullscreen, changing a space name, or changing the layout of the TotalSpaces grid. There are no
246
+ # arguments passed to the block.
247
+ #
248
+ # TotalSpaces.on_layout_change {puts "Spaces changed"}
249
+ #
250
+ # When you get a notification from this method, you should re-fetch any information about the spaces
251
+ # that you may be storing.
252
+ #
253
+ # There can only be one block registered at any time, the most recently registered one will
254
+ # be called.
255
+ #
256
+ def on_layout_change(&block)
257
+ $tsapi_on_layout_change_block = block # prevent CG
258
+ TSApi.tsapi_setLayoutChangedCallback(block)
259
+ end
260
+
261
+ # Cancel the layout change notification
262
+ #
263
+ def cancel_on_layout_change
264
+ $tsapi_on_layout_change_block = nil
265
+ TSApi.tsapi_unsetLayoutChangedCallback
266
+ end
267
+
268
+ # Get a list of all the windows on your mac
269
+ # It returns an array containing a hash for each space.
270
+ # The hash contains the space number (key :space_number) and an array of hashes, one
271
+ # for each window (key :windows). The windows are in front to back order.
272
+ # Each window hash contains a window_id, title, frame, app_name and is_on_all_spaces flag
273
+ #
274
+ # The below example would move the frontmost window to the next space to the right.
275
+ #
276
+ # windows = TotalSpaces.window_list
277
+ # if !windows.empty?
278
+ # current_space_windows = windows[TotalSpaces.current_space - 1]
279
+ # front_window = current_space_windows[:windows][0]
280
+ # TotalSpaces.move_window_to_space(front_window[:window_id], TotalSpaces.current_space + 1)
281
+ # end
282
+ #
283
+ end
284
+ def window_list
285
+ result = []
286
+ list = TSApi.tsapi_windowList
287
+ main_array = Spaces.new(list)
288
+
289
+ (0...main_array[:count]).each do |n|
290
+ result[n] = {}
291
+ windows_array = Space.new(main_array[:windows_arrays] + n * Space.size)
292
+ result[n][:space_number] = windows_array[:space_number]
293
+ result[n][:windows] = []
294
+ (0...windows_array[:count]).each do |m|
295
+ window_hash = result[n][:windows][m] = {}
296
+ window = Window.new(windows_array[:windows_array] + m * Window.size)
297
+ window_hash[:window_id] = window[:window_id]
298
+ window_hash[:title] = window[:title].dup.force_encoding("UTF-8")
299
+ window_hash[:frame] = window[:frame].dup.force_encoding("UTF-8")
300
+ window_hash[:is_on_all_spaces] = window[:is_on_all_spaces]
301
+ window_hash[:app_name] = window[:app_name].dup.force_encoding("UTF-8")
302
+ end
303
+ end
304
+
305
+ TSApi.tsapi_freeWindowList(list)
306
+
307
+ result
308
+ end
309
+
310
+ # Move a window to a given space
311
+ # The window_id parameter must be fetched using window_list.
312
+ # Returns false if the space_number or window_id is invalid.
313
+ #
314
+ def move_window_to_space(window_id, space_number)
315
+ TSApi.tsapi_moveWindowToSpace(window_id, space_number)
316
+ end
317
+ end
318
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: totalspaces
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stephen Sykes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ffi
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.11
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.11
30
+ description: This allows you to control the TotalSpaces desktop manager for mac from
31
+ ruby.
32
+ email: stephen@binaryage.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - README.rdoc
38
+ - MIT_LICENCE
39
+ - lib/totalspaces.rb
40
+ - lib/libtotalspacesapi.dylib
41
+ - lib/TSLib.h
42
+ homepage: http://github.com/binaryage/totalspaces-api
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options:
46
+ - --charset=UTF-8
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.23
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: TotalSpaces control from ruby
67
+ test_files: []