ruby-wmctrl 0.0.6 → 0.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4cf9848c86b0484717aa10282cad3b80d6fe4ea7
4
- data.tar.gz: 893e41f4b1da558a574473149ba4109a1a13f351
2
+ SHA256:
3
+ metadata.gz: 64b85024233d08a600bd914867fcf4e3250aa4c21e8ec45eb7bf31644c3a317c
4
+ data.tar.gz: d42e156ef9c64fd3b43664b3cc4738295528541c12cae7dd7d4897c34e9496e4
5
5
  SHA512:
6
- metadata.gz: b208af445e7333c390ea5ef42780e8f9738070520599ce4ee1957b09c5e130b8393ff0572f3ac5c933cf6bcd22d0ebc27e710af0d07e914c9488f0a62ac9a544
7
- data.tar.gz: 8286f7c16f86ffad0169ede09ce432a926fca52d8bc02e5c63121c089711b1d035ee8d0114606567be12458ec21eaefc15cee8dd2cd6e3aa619cf35ad0ce480d
6
+ metadata.gz: b83996d39afbf0b47c6b964673f0a147ac6dc10d49670f3dfac051092fb45684e9e114ec07378034e443b04c539fff7bb7cc564773484efc8931dc771b8e134b
7
+ data.tar.gz: 412805d6b06f93ba5fad169dc2192204cdfcbb410778c1459421a11c6d3d5891d9f6aab9507f265d96abd4342af2f8603ff6959936448794ad8d56e954e734f7
@@ -8,6 +8,7 @@ $CFLAGS << " " << glib.cflags
8
8
  $libs << " " << glib.libs
9
9
 
10
10
  dir_config("X11")
11
- if have_header('X11/Xlib.h') && have_library('X11')
11
+ if have_header('X11/Xlib.h') && have_library('X11') &&
12
+ have_header('X11/Xmu/WinUtil.h') && have_library('Xmu')
12
13
  create_makefile("wmctrl")
13
14
  end
@@ -35,16 +35,13 @@ static gchar *get_property (Display *disp, Window win,
35
35
  static Window *get_client_list (Display *disp, unsigned long *size);
36
36
  static gchar *get_window_class (Display *disp, Window win);
37
37
  static gchar *get_window_title (Display *disp, Window win);
38
- static int activate_window (Display *disp, Window win, gboolean switch_desktop);
39
- static int close_window (Display *disp, Window win);
38
+ static VALUE activate_window (Display *disp, Window win, gboolean switch_desktop);
39
+ static VALUE close_window (Display *disp, Window win);
40
40
  static gboolean wm_supports (Display *disp, const gchar *prop);
41
- static int window_move_resize (Display *disp, Window win, signed long grav,
42
- signed long x, signed long y, signed long w, signed long h);
43
- static int window_state (Display *disp, Window win,
44
- const char *action_str, const char *prop1_str, const char *prop2_str);
41
+ static VALUE window_move_resize (Display *disp, Window win, signed long grav, signed long x, signed long y, signed long w, signed long h);
42
+ static VALUE change_window_state (Display *disp, Window win, const char *action_str, const char *prop1_str, const char *prop2_str);
45
43
  static int window_to_desktop (Display *disp, Window win, int desktop);
46
- static void window_set_title (Display *disp, Window win, char *title, char mode);
47
- static int action_window (Display *disp, Window win, char mode, int argc, VALUE *argv);
44
+ static VALUE window_set_title (Display *disp, Window win, char *title, ID sym_id);
48
45
  static Window Select_Window(Display *dpy);
49
46
  static Window get_active_window(Display *disp);
50
47
  static Window get_target_window (Display *disp, VALUE obj);
@@ -53,7 +50,7 @@ static Window get_target_window (Display *disp, VALUE obj);
53
50
  static VALUE rb_wmctrl_class, key_id, key_title, key_pid, key_geometry,
54
51
  key_active, key_class, key_client_machine, key_desktop,
55
52
  key_viewport, key_workarea, key_current, key_showing_desktop, key_name,
56
- key_state, key_frame_extents, key_strut, key_exterior_frame;
53
+ key_state, key_window_type, key_frame_extents, key_strut, key_exterior_frame;
57
54
 
58
55
  static ID id_select, id_active, id_activate, id_close, id_move_resize,
59
56
  id_change_state, id_move_to_desktop, id_move_to_current,
@@ -283,6 +280,10 @@ static VALUE get_window_hash_data (Window win, Display *disp, Window window_acti
283
280
  Atom *window_state;
284
281
  gchar *state_name;
285
282
  VALUE state_ary;
283
+ unsigned long window_type_size;
284
+ Atom *window_type;
285
+ gchar *window_type_name;
286
+ VALUE window_type_ary;
286
287
  Atom *extents;
287
288
  unsigned long extents_size;
288
289
  VALUE extents_ary;
@@ -317,6 +318,21 @@ static VALUE get_window_hash_data (Window win, Display *disp, Window window_acti
317
318
  }
318
319
  rb_hash_aset(window_obj, key_state, state_ary);
319
320
 
321
+ /* window type */
322
+ if ((window_type = (Atom *)get_property(disp, win,
323
+ XA_ATOM, "_NET_WM_WINDOW_TYPE", &window_type_size)) != NULL) {
324
+ window_type_ary = rb_ary_new();
325
+ for (j = 0; j < window_type_size / sizeof(Atom); j++) {
326
+ window_type_name = XGetAtomName(disp, window_type[j]);
327
+ rb_ary_push(window_type_ary, rb_str_new2(window_type_name));
328
+ g_free(window_type_name);
329
+ }
330
+ g_free(window_type);
331
+ } else {
332
+ window_type_ary = Qnil;
333
+ }
334
+ rb_hash_aset(window_obj, key_window_type, window_type_ary);
335
+
320
336
  /* frame extents */
321
337
  if ((extents = (unsigned long *)get_property(disp, win,
322
338
  XA_CARDINAL, "_NET_FRAME_EXTENTS", &extents_size)) != NULL) {
@@ -828,7 +844,7 @@ static VALUE rb_wmctrl_change_number_of_desktops (VALUE self, VALUE num) {
828
844
  return Qtrue;
829
845
  }
830
846
 
831
- static int activate_window (Display *disp, Window win, gboolean switch_desktop)
847
+ static VALUE activate_window (Display *disp, Window win, gboolean switch_desktop)
832
848
  {
833
849
  unsigned long *desktop;
834
850
 
@@ -853,12 +869,15 @@ static int activate_window (Display *disp, Window win, gboolean switch_desktop)
853
869
  client_msg(disp, win, "_NET_ACTIVE_WINDOW", 0, 0, 0, 0, 0);
854
870
  XMapRaised(disp, win);
855
871
 
856
- return True;
872
+ return Qtrue;
857
873
  }
858
874
 
859
- static int close_window (Display *disp, Window win)
875
+ static VALUE close_window (Display *disp, Window win)
860
876
  {
861
- return client_msg(disp, win, "_NET_CLOSE_WINDOW", 0, 0, 0, 0, 0);
877
+ if (client_msg(disp, win, "_NET_CLOSE_WINDOW", 0, 0, 0, 0, 0)) {
878
+ return Qtrue;
879
+ }
880
+ return Qfalse;
862
881
  }
863
882
 
864
883
  static gboolean wm_supports (Display *disp, const gchar *prop)
@@ -885,39 +904,42 @@ static gboolean wm_supports (Display *disp, const gchar *prop)
885
904
  return FALSE;
886
905
  }
887
906
 
888
- static int window_move_resize (Display *disp, Window win, signed long grav,
889
- signed long x, signed long y, signed long w, signed long h)
907
+ static VALUE window_move_resize (Display *disp, Window win, signed long grav, signed long x, signed long y, signed long w, signed long h)
890
908
  {
891
- unsigned long grflags;
892
- grflags = grav;
893
- if (x != -1) grflags |= (1 << 8);
894
- if (y != -1) grflags |= (1 << 9);
895
- if (w != -1) grflags |= (1 << 10);
896
- if (h != -1) grflags |= (1 << 11);
897
-
898
- p_verbose("move_resize: %lu %ld %ld %ld %ld\n", grflags, x, y, w, h);
899
-
900
- if (wm_supports(disp, "_NET_MOVERESIZE_WINDOW")){
901
- return client_msg(disp, win, "_NET_MOVERESIZE_WINDOW",
902
- grflags, (unsigned long)x, (unsigned long)y, (unsigned long)w, (unsigned long)h);
903
- }
904
- else {
909
+ p_verbose("move_resize: %lu %ld %ld %ld %ld\n", grav, x, y, w, h);
910
+ if ((grav >= 0) && wm_supports(disp, "_NET_MOVERESIZE_WINDOW")) {
911
+ unsigned long grflags;
912
+ grflags = grav;
913
+ if (x != -1) {
914
+ grflags |= (1 << 8);
915
+ }
916
+ if (y != -1) {
917
+ grflags |= (1 << 9);
918
+ }
919
+ if (w != -1) {
920
+ grflags |= (1 << 10);
921
+ }
922
+ if (h != -1) {
923
+ grflags |= (1 << 11);
924
+ }
925
+ if (client_msg(disp, win, "_NET_MOVERESIZE_WINDOW", grflags, (unsigned long) x, (unsigned long) y, (unsigned long) w, (unsigned long) h)) {
926
+ return Qtrue;
927
+ }
928
+ return Qfalse;
929
+ } else {
905
930
  p_verbose("WM doesn't support _NET_MOVERESIZE_WINDOW. Gravity will be ignored.\n");
906
931
  if ((w < 1 || h < 1) && (x >= 0 && y >= 0)) {
907
932
  XMoveWindow(disp, win, x, y);
908
- }
909
- else if ((x < 0 || y < 0) && (w >= 1 && h >= -1)) {
933
+ } else if ((x < 0 || y < 0) && (w >= 1 && h >= -1)) {
910
934
  XResizeWindow(disp, win, w, h);
911
- }
912
- else if (x >= 0 && y >= 0 && w >= 1 && h >= 1) {
935
+ } else if (x >= 0 && y >= 0 && w >= 1 && h >= 1) {
913
936
  XMoveResizeWindow(disp, win, x, y, w, h);
914
937
  }
915
- return EXIT_SUCCESS;
938
+ return Qtrue;
916
939
  }
917
940
  }
918
941
 
919
- static int window_state (Display *disp, Window win,
920
- const char *action_str, const char *prop1_str, const char *prop2_str)
942
+ static VALUE change_window_state (Display *disp, Window win, const char *action_str, const char *prop1_str, const char *prop2_str)
921
943
  {
922
944
  unsigned long action;
923
945
  Atom prop1 = 0;
@@ -927,14 +949,11 @@ static int window_state (Display *disp, Window win,
927
949
  /* action */
928
950
  if (strcmp(action_str, "remove") == 0) {
929
951
  action = _NET_WM_STATE_REMOVE;
930
- }
931
- else if (strcmp(action_str, "add") == 0) {
952
+ } else if (strcmp(action_str, "add") == 0) {
932
953
  action = _NET_WM_STATE_ADD;
933
- }
934
- else if (strcmp(action_str, "toggle") == 0) {
954
+ } else if (strcmp(action_str, "toggle") == 0) {
935
955
  action = _NET_WM_STATE_TOGGLE;
936
- }
937
- else {
956
+ } else {
938
957
  rb_raise(rb_eArgError, "Invalid action. Use either remove, add or toggle.");
939
958
  }
940
959
 
@@ -953,7 +972,10 @@ static int window_state (Display *disp, Window win,
953
972
  g_free(tmp2);
954
973
  g_free(tmp_prop2);
955
974
  }
956
- return client_msg(disp, win, "_NET_WM_STATE", action, (unsigned long)prop1, (unsigned long)prop2, 0, 0);
975
+ if (client_msg(disp, win, "_NET_WM_STATE", action, (unsigned long) prop1, (unsigned long) prop2, 0, 0)) {
976
+ return Qtrue;
977
+ }
978
+ return Qnil;
957
979
  }
958
980
 
959
981
  static int window_to_desktop (Display *disp, Window win, int desktop)
@@ -979,7 +1001,7 @@ static int window_to_desktop (Display *disp, Window win, int desktop)
979
1001
  return client_msg(disp, win, "_NET_WM_DESKTOP", (unsigned long)desktop, 0, 0, 0, 0);
980
1002
  }
981
1003
 
982
- static void window_set_title (Display *disp, Window win, char *title, char mode)
1004
+ static VALUE window_set_title (Display *disp, Window win, char *title, ID sym_id)
983
1005
  {
984
1006
  gchar *title_utf8;
985
1007
  gchar *title_local;
@@ -987,109 +1009,38 @@ static void window_set_title (Display *disp, Window win, char *title, char mode)
987
1009
  if (envir_utf8) {
988
1010
  title_utf8 = g_strdup(title);
989
1011
  title_local = NULL;
990
- }
991
- else {
992
- if (! (title_utf8 = g_locale_to_utf8(title, -1, NULL, NULL, NULL))) {
1012
+ } else {
1013
+ if (!(title_utf8 = g_locale_to_utf8(title, -1, NULL, NULL, NULL))) {
993
1014
  title_utf8 = g_strdup(title);
994
1015
  }
995
1016
  title_local = g_strdup(title);
996
1017
  }
997
1018
 
998
- if (mode == 'T' || mode == 'N') {
1019
+ if ((sym_id == id_set_title_both) || (sym_id == id_set_title_long)) {
999
1020
  /* set name */
1000
1021
  if (title_local) {
1001
- XChangeProperty(disp, win, XA_WM_NAME, XA_STRING, 8, PropModeReplace,
1002
- (const unsigned char *)title_local, strlen(title_local));
1003
- }
1004
- else {
1022
+ XChangeProperty(disp, win, XA_WM_NAME, XA_STRING, 8, PropModeReplace, (const unsigned char *) title_local, strlen(title_local));
1023
+ } else {
1005
1024
  XDeleteProperty(disp, win, XA_WM_NAME);
1006
1025
  }
1007
- XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_NAME", False),
1008
- XInternAtom(disp, "UTF8_STRING", False), 8, PropModeReplace,
1009
- (const unsigned char *)title_utf8, strlen(title_utf8));
1026
+ XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_NAME", False), XInternAtom(disp, "UTF8_STRING", False), 8, PropModeReplace, (const unsigned char *) title_utf8, strlen(title_utf8));
1010
1027
  }
1011
1028
 
1012
- if (mode == 'T' || mode == 'I') {
1029
+ if ((sym_id == id_set_title_both) || (sym_id == id_set_title_short)) {
1013
1030
  /* set icon name */
1014
1031
  if (title_local) {
1015
- XChangeProperty(disp, win, XA_WM_ICON_NAME, XA_STRING, 8, PropModeReplace,
1016
- (const unsigned char *)title_local, strlen(title_local));
1017
- }
1018
- else {
1032
+ XChangeProperty(disp, win, XA_WM_ICON_NAME, XA_STRING, 8, PropModeReplace, (const unsigned char *) title_local, strlen(title_local));
1033
+ } else {
1019
1034
  XDeleteProperty(disp, win, XA_WM_ICON_NAME);
1020
1035
  }
1021
- XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_ICON_NAME", False),
1022
- XInternAtom(disp, "UTF8_STRING", False), 8, PropModeReplace,
1023
- (const unsigned char *)title_utf8, strlen(title_utf8));
1036
+ XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_ICON_NAME", False), XInternAtom(disp, "UTF8_STRING", False), 8, PropModeReplace, (const unsigned char *) title_utf8, strlen(title_utf8));
1024
1037
  }
1025
1038
 
1026
1039
  g_free(title_utf8);
1027
- g_free(title_local);
1028
- }
1029
-
1030
- static int action_window (Display *disp, Window win, char mode, int argc, VALUE *argv)
1031
- {
1032
- p_verbose("Using window: 0x%.8lx\n", win);
1033
- switch (mode) {
1034
- case 'a':
1035
- if (argc == 0) {
1036
- return activate_window(disp, win, TRUE);
1037
- }
1038
- case 'c':
1039
- if (argc == 0) {
1040
- return close_window(disp, win);
1041
- }
1042
- case 'e':
1043
- /* resize/move the window around the desktop => -r -e */
1044
- if (argc == 5) {
1045
- int grav, x, y, w, h;
1046
- grav = FIX2INT(argv[0]);
1047
- x = FIX2INT(argv[1]);
1048
- y = FIX2INT(argv[2]);
1049
- w = FIX2INT(argv[3]);
1050
- h = FIX2INT(argv[4]);
1051
- if (grav >= 0) {
1052
- return window_move_resize(disp, win, grav, x, y, w, h);
1053
- }
1054
- }
1055
- break;
1056
- case 'b':
1057
- /* change state of a window => -r -b */
1058
- if (argc == 2 || argc == 3) {
1059
- const char *action, *prop1, *prop2;
1060
- action = StringValuePtr(argv[0]);
1061
- prop1 = StringValuePtr(argv[1]);
1062
- if (argc == 3) {
1063
- prop2 = StringValuePtr(argv[2]);
1064
- } else {
1065
- prop2 = NULL;
1066
- }
1067
- return window_state(disp, win, action, prop1, prop2);
1068
- }
1069
- case 't':
1070
- /* move the window to the specified desktop => -r -t */
1071
- if (argc == 1) {
1072
- return window_to_desktop(disp, win, FIX2INT(argv[0]));
1073
- }
1074
- case 'R':
1075
- /* move the window to the current desktop and activate it => -r */
1076
- if (argc == 0) {
1077
- if (window_to_desktop(disp, win, -1)) {
1078
- usleep(100000); /* 100 ms - make sure the WM has enough
1079
- time to move the window, before we activate it */
1080
- return activate_window(disp, win, FALSE);
1081
- }
1082
- else {
1083
- return False;
1084
- }
1085
- }
1086
- case 'N': case 'I': case 'T':
1087
- if (argc == 1) {
1088
- window_set_title(disp, win, StringValuePtr(argv[0]), mode);
1089
- return True;
1090
- }
1040
+ if (title_local) {
1041
+ g_free(title_local);
1091
1042
  }
1092
- rb_raise(rb_eArgError, "Invalid argument of action_window.");
1043
+ return Qtrue;
1093
1044
  }
1094
1045
 
1095
1046
  static Window Select_Window(Display *dpy)
@@ -1191,31 +1142,63 @@ static Window get_target_window (Display *disp, VALUE obj)
1191
1142
  }
1192
1143
 
1193
1144
  /*
1194
- @overload action_window(wid, cmd, *args)
1195
-
1196
- Manage windows.
1197
- @param wid Window ID
1198
- @param cmd [Symbol] Symbol of command
1199
- @param args [Array] Arguments for the command
1200
-
1201
- @return [boolean] true if succeeded. Otherwise, false.
1202
-
1203
- @example
1204
- wm.action_window(wid, :activate)
1205
- wm.action_window(wid, :close)
1206
- wm.action_window(wid, :move_resize, grav, x, y, w, h)
1207
- wm.action_window(wid, :change_state, add, prop1, prop2 = nil)
1208
- wm.action_window(wid, :change_state, remove, prop1, prop2 = nil)
1209
- wm.action_window(wid, :change_state, toggle, prop1, prop2 = nil)
1210
- wm.action_window(wid, :move_to_desktop, desktop_id)
1211
- wm.action_window(wid, :move_to_current)
1212
- wm.action_window(wid, :set_title_long, str)
1213
- wm.action_window(wid, :set_title_short, str)
1214
- wm.action_window(wid, :set_title_both, str)
1145
+ Manage a window.
1146
+ @overload action_window(wid, :activate)
1147
+ Activate a window.
1148
+ @param [Integer] wid Window ID
1149
+ @return [boolean] true if succeeded. Otherwise, false.
1150
+ @overload action_window(wid, :close)
1151
+ Close a window
1152
+ @param [Integer] wid Window ID
1153
+ @return [boolean] true if succeeded. Otherwise, false.
1154
+ @overload action_window(wid, :move_resize, grav, x, y, w, h)
1155
+ @param [Integer] wid Window ID
1156
+ @param [Integer] grav Gravity
1157
+ @param [Integer] x X coordinate
1158
+ @param [Integer] y Y coordinate
1159
+ @param [Integer] w Width
1160
+ @param [Integer] h Height
1161
+ @return [boolean] true if succeeded. Otherwise, false.
1162
+ @overload action_window(wid, :change_state, "add", prop1, prop2 = nil)
1163
+ @param [Integer] wid Window ID
1164
+ @param [String] prop1 String of _NET_WM_STATE type.
1165
+ @param [String] prop2 String of _NET_WM_STATE type.
1166
+ @return [boolean] true if succeeded. Otherwise, false.
1167
+ @overload action_window(wid, :change_state, "remove", prop1, prop2 = nil)
1168
+ @param [Integer] wid Window ID
1169
+ @param [String] prop1 String of _NET_WM_STATE type.
1170
+ @param [String] prop2 String of _NET_WM_STATE type.
1171
+ @return [boolean] true if succeeded. Otherwise, false.
1172
+ @overload action_window(wid, :change_state, "toggle", prop1, prop2 = nil)
1173
+ @param [Integer] wid Window ID
1174
+ @param [String] prop1 String of _NET_WM_STATE type.
1175
+ @param [String] prop2 String of _NET_WM_STATE type.
1176
+ @return [boolean] true if succeeded. Otherwise, false.
1177
+ @overload action_window(wid, :move_to_desktop, desktop_id)
1178
+ @param [Integer] wid Window ID
1179
+ @param [Integer] desktop_id Desktop ID
1180
+ @return [boolean] true if succeeded. Otherwise, false.
1181
+ @overload action_window(wid, :move_to_current)
1182
+ @param [Integer] wid Window ID
1183
+ @return [boolean] true if succeeded. Otherwise, false.
1184
+ @overload action_window(wid, :set_title_long, str)
1185
+ @param [Integer] wid Window ID
1186
+ @return [boolean] true if succeeded. Otherwise, false.
1187
+ @overload action_window(wid, :set_title_short, str)
1188
+ @param [Integer] wid Window ID
1189
+ @return [boolean] true if succeeded. Otherwise, false.
1190
+ @overload action_window(wid, :set_title_both, str)
1191
+ @param [Integer] wid Window ID
1192
+ @return [boolean] true if succeeded. Otherwise, false.
1193
+
1194
+ @note
1195
+ The arguments of prop1 and prop2 for :change_state command are strings
1196
+ that mean type of _NET_WM_STATE.
1197
+ For example, For example, we use "modal" or "MODAL" for _NET_WM_STATE_MODAL.
1198
+ See also http://standards.freedesktop.org/wm-spec/wm-spec-latest.html
1215
1199
  */
1216
1200
  static VALUE rb_wmctrl_action_window(int argc, VALUE *argv, VALUE self) {
1217
- Window wid;
1218
- int mode;
1201
+ Window win;
1219
1202
  ID sym_id;
1220
1203
  Display **ptr, *disp;
1221
1204
  Data_Get_Struct(self, Display*, ptr);
@@ -1223,34 +1206,67 @@ static VALUE rb_wmctrl_action_window(int argc, VALUE *argv, VALUE self) {
1223
1206
  if (argc < 2) {
1224
1207
  rb_raise(rb_eArgError, "Need more than one argument.");
1225
1208
  }
1226
- wid = get_target_window(disp, argv[0]);
1209
+ win = get_target_window(disp, argv[0]);
1227
1210
  sym_id = SYM2ID(argv[1]);
1211
+ argc = argc - 2;
1212
+ argv = argv + 2;
1213
+ p_verbose("Using window: 0x%.8lx\n", win);
1228
1214
  if (sym_id == id_activate) {
1229
- mode = 'a';
1215
+ if (argc == 0) {
1216
+ return activate_window(disp, win, TRUE);
1217
+ }
1230
1218
  } else if (sym_id == id_close) {
1231
- mode = 'c';
1219
+ if (argc == 0) {
1220
+ return close_window(disp, win);
1221
+ }
1232
1222
  } else if (sym_id == id_move_resize) {
1233
- mode = 'e';
1223
+ /* resize/move the window around the desktop => -r -e */
1224
+ if (argc == 5) {
1225
+ int grav, x, y, w, h;
1226
+ grav = FIX2INT(argv[0]);
1227
+ x = FIX2INT(argv[1]);
1228
+ y = FIX2INT(argv[2]);
1229
+ w = FIX2INT(argv[3]);
1230
+ h = FIX2INT(argv[4]);
1231
+ return window_move_resize(disp, win, grav, x, y, w, h);
1232
+ }
1234
1233
  } else if (sym_id == id_change_state) {
1235
- mode = 'b';
1234
+ /* change state of a window => -r -b */
1235
+ if (argc == 2 || argc == 3) {
1236
+ const char *action, *prop1, *prop2;
1237
+ action = StringValuePtr(argv[0]);
1238
+ prop1 = StringValuePtr(argv[1]);
1239
+ if (argc == 3) {
1240
+ prop2 = StringValuePtr(argv[2]);
1241
+ } else {
1242
+ prop2 = NULL;
1243
+ }
1244
+ return change_window_state(disp, win, action, prop1, prop2);
1245
+ }
1236
1246
  } else if (sym_id == id_move_to_desktop) {
1237
- mode = 't';
1247
+ /* move the window to the specified desktop => -r -t */
1248
+ if (argc == 1) {
1249
+ if (window_to_desktop(disp, win, FIX2INT(argv[0]))) {
1250
+ return Qtrue;
1251
+ }
1252
+ return Qfalse;
1253
+ }
1238
1254
  } else if (sym_id == id_move_to_current) {
1239
- mode = 'R';
1240
- } else if (sym_id == id_set_title_long) {
1241
- mode = 'N';
1242
- } else if (sym_id == id_set_title_short) {
1243
- mode = 'I';
1244
- } else if (sym_id == id_set_title_both) {
1245
- mode = 'T';
1246
- } else {
1247
- rb_raise(rb_eStandardError, "Invalid argument of action_window.");
1248
- }
1249
- if (action_window(disp, wid, mode, argc - 2, (argv + 2))) {
1250
- return Qtrue;
1251
- } else {
1252
- return Qfalse;
1255
+ /* move the window to the current desktop and activate it => -r */
1256
+ if (argc == 0) {
1257
+ if (window_to_desktop(disp, win, -1)) {
1258
+ usleep(100000);
1259
+ /* 100 ms - make sure the WM has enough time to move the window, before we activate it */
1260
+ return activate_window(disp, win, FALSE);
1261
+ }
1262
+ return Qfalse;
1263
+ }
1264
+ } else if (sym_id == id_set_title_long || sym_id == id_set_title_short || sym_id == id_set_title_both) {
1265
+ if (argc == 1) {
1266
+ return window_set_title(disp, win, StringValuePtr(argv[0]), sym_id);
1267
+ }
1253
1268
  }
1269
+ rb_raise(rb_eStandardError, "Invalid argument of action_window.");
1254
1270
  }
1255
1271
 
1256
1272
  /*
@@ -1317,6 +1333,7 @@ void Init_wmctrl()
1317
1333
  key_showing_desktop = ID2SYM(rb_intern("showing_desktop"));
1318
1334
  key_name = ID2SYM(rb_intern("name"));
1319
1335
  key_state = ID2SYM(rb_intern("state"));
1336
+ key_window_type = ID2SYM(rb_intern("window_type"));
1320
1337
  key_frame_extents = ID2SYM(rb_intern("frame_extents"));
1321
1338
  key_strut = ID2SYM(rb_intern("strut"));
1322
1339
  key_exterior_frame = ID2SYM(rb_intern("exterior_frame"));
@@ -1,3 +1,3 @@
1
1
  class WMCtrl
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -1,6 +1,19 @@
1
1
  require 'wmctrl.so'
2
2
 
3
3
  class WMCtrl
4
+ NOT_USE_NET_MOVERESIZE_WINDOW = -1
5
+ GRAVITY_DEFAULT = 0
6
+ GRAVITY_NORTH_WEST = 1
7
+ GRAVITY_NORTH = 2
8
+ GRAVITY_NORTH_EAST = 3
9
+ GRAVITY_WEST = 4
10
+ GRAVITY_CENTER = 5
11
+ GRAVITY_EAST = 6
12
+ GRAVITY_SOUTH_WEST = 7
13
+ GRAVITY_SOUTH = 8
14
+ GRAVITY_SOUTH_EAST = 9
15
+ GRAVITY_STATIC = 10
16
+
4
17
  def self.instance
5
18
  @wmctrl ||= self.new
6
19
  end
@@ -85,10 +98,36 @@ class WMCtrl
85
98
  self[:active]
86
99
  end
87
100
 
88
- STATE_FULLSCREEN = "_NET_WM_STATE_FULLSCREEN"
89
-
90
101
  def fullscreen?
91
- self[:state].include?(STATE_FULLSCREEN)
102
+ self[:state].include?("_NET_WM_STATE_FULLSCREEN")
103
+ end
104
+
105
+ def modal?
106
+ self[:state].include?("_NET_WM_STATE_MODAL")
107
+ end
108
+
109
+ def maximized_vertically?
110
+ self[:state].include?("_NET_WM_STATE_MAXIMIZED_VERT")
111
+ end
112
+
113
+ def maximized_horizontally?
114
+ self[:state].include?("_NET_WM_STATE_MAXIMIZED_HORZ")
115
+ end
116
+
117
+ def shaded?
118
+ self[:state].include?("_NET_WM_STATE_SHADED")
119
+ end
120
+
121
+ def hidden?
122
+ self[:state].include?("_NET_WM_STATE_HIDDEN")
123
+ end
124
+
125
+ def skipped_by_taskbar?
126
+ self[:state].include?("_NET_WM_STATE_SKIP_TASKBAR")
127
+ end
128
+
129
+ def skipped_by_pager?
130
+ self[:state].include?("_NET_WM_STATE_SKIP_PAGER")
92
131
  end
93
132
 
94
133
  def action(*args)
@@ -116,6 +155,9 @@ class WMCtrl
116
155
  # @option opts [Integer] :width Width of window
117
156
  # @option opts [Integer] :height Height of window
118
157
  # @option opts [Integer,:current] :desktop Desktop number
158
+ # @option opts [Integer] :gravity Number meaning gravity: NOT_USE_NET_MOVERESIZE_WINDOW,
159
+ # GRAVITY_DEFAULT, GRAVITY_NORTH_WEST, GRAVITY_NORTH, GRAVITY_NORTH_EAST, GRAVITY_WEST, GRAVITY_CENTER,
160
+ # GRAVITY_EAST, GRAVITY_SOUTH_WEST, GRAVITY_SOUTH, GRAVITY_SOUTH_EAST, GRAVITY_STATIC
119
161
  def place(opts = {})
120
162
  if opts[:desktop]
121
163
  if opts[:desktop] == :current
@@ -124,6 +166,7 @@ class WMCtrl
124
166
  action(:move_to_desktop, opts[:desktop])
125
167
  end
126
168
  end
169
+ gravity = opts[:gravity] || GRAVITY_DEFAULT
127
170
  x = self[:exterior_frame][0]
128
171
  y = self[:exterior_frame][1]
129
172
  width = self[:exterior_frame][2]
@@ -134,7 +177,7 @@ class WMCtrl
134
177
  height = opts[:height] if opts[:height] && (opts[:height] != height)
135
178
  x = opts[:x] if opts[:x] && (opts[:x] != x)
136
179
  y = opts[:y] if opts[:y] && (opts[:y] != y)
137
- action(:move_resize, 0, x + self[:frame_extents][0], y + self[:frame_extents][1], width - extent_horizontal, height - extent_vertical)
180
+ action(:move_resize, gravity, x + self[:frame_extents][0], y + self[:frame_extents][1], width - extent_horizontal, height - extent_vertical)
138
181
  end
139
182
 
140
183
  def position
@@ -148,9 +191,15 @@ class WMCtrl
148
191
  list_desktops.map { |hash| WMCtrl::Desktop.new(hash) }
149
192
  end
150
193
 
151
- # @param [Array] conditions An array of condition hash. The values of hash are tested by the method ===.
152
- # @return [Array] An array of WMCtrl::Window
153
- def windows(*conditions)
194
+ # @param [Array] conditions An array of condition hash.
195
+ # The keys of the hash are keys of WMCtrl::Window#[].
196
+ # The values of the hash are tested by the method ===.
197
+ # Keys of each condition are combined by logical product and
198
+ # all conditions are combined by logical sum.
199
+ # @yield [WMCtrl::Window] Test window by block
200
+ # @return [Array] An array of WMCtrl::Window including windows
201
+ # matched by the conditions and the block.
202
+ def windows(*conditions, &block)
154
203
  wins = list_windows(true).map { |hash| WMCtrl::Window.new(hash) }
155
204
  unless conditions.empty?
156
205
  wins_selected = []
@@ -167,6 +216,9 @@ class WMCtrl
167
216
  end
168
217
  wins = wins_selected
169
218
  end
219
+ if block_given?
220
+ wins.delete_if { |win| !yield(win) }
221
+ end
170
222
  wins
171
223
  end
172
224
  end
@@ -11,29 +11,29 @@ describe WMCtrl do
11
11
 
12
12
  it "should get an array of hashes." do
13
13
  wins = wm.list_windows
14
- wins.should be_an_instance_of Array
14
+ expect(wins).to be_an_instance_of Array
15
15
  wins.each do |w|
16
- w.should be_an_instance_of Hash
16
+ expect(w).to be_an_instance_of Hash
17
17
  end
18
18
  end
19
19
 
20
20
  it "should get an array of hashes." do
21
21
  desktops = wm.list_desktops
22
- desktops.should be_an_instance_of Array
22
+ expect(desktops).to be_an_instance_of Array
23
23
  desktops.each do |w|
24
- w.should be_an_instance_of Hash
24
+ expect(w).to be_an_instance_of Hash
25
25
  end
26
26
  end
27
27
 
28
28
  it "should get information of window manager." do
29
- wm.info.should be_an_instance_of Hash
29
+ expect(wm.info).to be_an_instance_of Hash
30
30
  end
31
31
 
32
32
  it "should get an array." do
33
33
  sp = wm.supported
34
- sp.should be_an_instance_of Array
34
+ expect(sp).to be_an_instance_of Array
35
35
  sp.each do |prop|
36
- prop.should be_an_instance_of String
36
+ expect(prop).to be_an_instance_of String
37
37
  end
38
38
  end
39
39
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-wmctrl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takayuki YAMAGUCHI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-05 00:00:00.000000000 Z
11
+ date: 2018-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -112,9 +112,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  version: '0'
113
113
  requirements: []
114
114
  rubyforge_project:
115
- rubygems_version: 2.0.3
115
+ rubygems_version: 2.7.3
116
116
  signing_key:
117
117
  specification_version: 4
118
118
  summary: Ruby bindings to control windows
119
119
  test_files: []
120
- has_rdoc: