Mouvement dans les spaces avec MacRuby (et Cocoa)
Dans le cadre du développement de RConsole, je me suis demandé comment faire pour déplacer une fenêtre d'un bureau (Space) à un autre. L'idée et de ne pas vous obliger à passer brutalement d'un bureau à un autre quand on active une application. Dans le cas d'un outil comme Mail ou Pages, cela se comprend très bien, mais pour un outil comme RConsole, il est beaucoup plus agréable de voir la fenêtre se réactiver sur le bureau courant.
Une recherche sur internet peut nous en apprendre beaucoup, dont le fait qu'il semble que pour le moment Apple ne documente pas les APIs nécessaires à ce travail. Il semble que Cupertino n'estime pas que ces APIs soient totalement finalisées. Quoi qu'il en soit, c'est comme toujours, ce qu'Apple ne documente pas reste utilisable ;)
Je me suis donc amusé à me faire une petite classe Objective-C permettant de jouer avec les bureaux. Dans les faits, ma classe contient 4 méthodes :
- - (NSInteger)spaceNumber; permets de récupérer le numéro du bureau courant.
- - (void)moveWindowToCurrentSpace:(NSWindow *)win; permets de déplacer la fenêtre passée en paramètre vers le bureau courant.
- - (void)moveWindow:(NSWindow *)win toSpaceNumber:(NSInteger)space; permets de déplacer la fenêtre passée en paramètre vers un bureau donné.
- - (NSInteger)getSpaceNumberOfWindow:(NSWindow *)win; donne le numéro du bureau sur lequel se trouve une fenêtre donnée.
Voici ce que cela donne :
Space.h 1 //
2 // Spaces.h
3 // RConsole
4 //
5 // Created by greg on 12/03/10.
6 // Copyright 2010 Grégoire Lejeune. All rights reserved.
7 //
8
9 #import <Cocoa/Cocoa.h>
10 #import <Foundation/Foundation.h>
11
12 @interface Spaces : NSObject {
13
14 }
15
16 - (NSInteger)spaceNumber;
17 - (void)moveWindowToCurrentSpace:(NSWindow *)win;
18 - (void)moveWindow:(NSWindow *)win toSpaceNumber:(NSInteger)space;
19 - (NSInteger)getSpaceNumberOfWindow:(NSWindow *)win;
20 @end
1 //
2 // Spaces.m
3 // RConsole
4 //
5 // Created by greg on 12/03/10.
6 // Copyright 2010 Grégoire Lejeune. All rights reserved.
7 //
8
9 #import "Spaces.h"
10
11 @implementation Spaces
12
13 - (NSInteger)spaceNumber {
14 NSInteger space = -1;
15 CGSGetWorkspace(_CGSDefaultConnection(), &space);
16 return space;
17 }
18
19 - (NSInteger)getSpaceNumberOfWindow:(NSWindow *)win {
20 NSInteger windowId = [win windowNumber];
21 NSInteger space = -1;
22 CGSGetWindowWorkspace(_CGSDefaultConnection(), windowId, &space);
23 return space;
24 }
25
26 - (void)moveWindowToCurrentSpace:(NSWindow *)win {
27 [self moveWindow:win toSpaceNumber:[self spaceNumber]];
28 }
29
30 - (void)moveWindow:(NSWindow *)win toSpaceNumber:(NSInteger)space {
31 NSInteger windowId = [win windowNumber];
32 if(windowId != -1) {
33 CGSMoveWorkspaceWindowList(_CGSDefaultConnection(), &windowId, 1, space);
34 }
35 }
36 @end
Sachant qu'utiliser une classe Objective-C se fait aussi naturellement qu'utiliser une classe Ruby avec MacRuby, voici un petit exemple :
1 class MyController
2 attr_accessor :myWindow
3
4 def initialize
5 @space = Space.new
6 end
7
8 # ...
9
10 def moveMyWindowToSpace( spaceNumber )
11 myWindowSpace = @space.getSpaceNumberOfWindow( myWindow )
12
13 if myWindowSpace != spaceNumber
14 @space.moveWindow( myWindowSpace, toSpaceNumber:spaceNumber )
15 end
16 end
17
18 def moveMyWindowToCurrentSpace
19 myWindowSpace = @space.getSpaceNumberOfWindow( myWindow )
20
21 if myWindowSpace != spaceNumber
22 @space.moveWindowToCurrentSpace( myWindow )
23 end
24 end
25 end