ruby-dbus 0.11.2 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12bb637315162a316a583bcbd48c77eb7904fdc1
4
- data.tar.gz: 93baea47e50c7f48fad776508949dea27ab9c6e7
3
+ metadata.gz: 25c36fdb17d7d5c19b83d451de704117b285fb56
4
+ data.tar.gz: 3f6ddb8bb599e3cd616a1e3ebf9f15394e3acd17
5
5
  SHA512:
6
- metadata.gz: 5fc62a23577d52c11d8496090e9740e09a8be730ac115e08796568eb055c4282ddba09dafb66527272d25e7f8a50fd8f447a9876df377691b23e364a9c230b07
7
- data.tar.gz: 41d4b093c212b6e5854060dd314274ef7847db14c3cb287f7e35e6703a090ab77d5c9bda1b3061da26c6a8d89c461642815a95e74a7f0862d27a34a198680585
6
+ metadata.gz: 0fe993c938add6a07d8432c3ae846fa93bf3b75bf6403dd04271f9401c09b41de3dbdd5487567500fe21d5abe1ec6ec8b0b8bd98c82c00ad9932253cfb5de9bb
7
+ data.tar.gz: 02d8d3c914d5c3b74b759e8e7eabce7bb1aa6a9c7cd1620645ed69f345639e85ab00353757502440c6fb601b6d11c9ac4df290c60eb576c5d49e1af9deeb47b7
data/NEWS CHANGED
@@ -7,6 +7,15 @@ Note about bug numbers:
7
7
 
8
8
  == Unreleased
9
9
 
10
+ == Ruby D-Bus 0.12.0 - 2016-09-12
11
+
12
+ API:
13
+ * Added proxy objects whose methods return single values instead of arrays
14
+ (use Service#[] instead of Service#object; Issue#30).
15
+
16
+ Requirements:
17
+ * Require ruby 2.0.0, stopped supporting 1.9.3.
18
+
10
19
  == Ruby D-Bus 0.11.2 - 2016-09-11
11
20
 
12
21
  Bug fixes:
data/README.md CHANGED
@@ -31,7 +31,7 @@ via [UPower](http://upower.freedesktop.org/docs/UPower.html#UPower:OnBattery)
31
31
  require "dbus"
32
32
  sysbus = DBus.system_bus
33
33
  upower_service = sysbus["org.freedesktop.UPower"]
34
- upower_object = upower_service.object "/org/freedesktop/UPower"
34
+ upower_object = upower_service["/org/freedesktop/UPower"]
35
35
  upower_object.introspect
36
36
  upower_interface = upower_object["org.freedesktop.UPower"]
37
37
  on_battery = upower_interface["OnBattery"]
@@ -43,7 +43,7 @@ via [UPower](http://upower.freedesktop.org/docs/UPower.html#UPower:OnBattery)
43
43
 
44
44
  ## Requirements
45
45
 
46
- - Ruby 1.9.3 or 2.0
46
+ - Ruby 2.0 or newer.
47
47
 
48
48
 
49
49
  ## Installation
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.2
1
+ 0.12.0
@@ -24,7 +24,7 @@ is simply "dbus"
24
24
 
25
25
  1. {DBus.session_bus Connect to the session bus};
26
26
  {DBus::Connection#[] get the screensaver service}
27
- {DBus::Service#object and its screensaver object}.
27
+ {DBus::Service#[] and its screensaver object}.
28
28
  2. Perform {DBus::ProxyObject#introspect explicit introspection}
29
29
  to define the interfaces and methods
30
30
  on the {DBus::ProxyObject object proxy}
@@ -32,9 +32,10 @@ is simply "dbus"
32
32
  3. Call one of its methods in a loop, solving [xkcd#196](http://xkcd.com/196).
33
33
 
34
34
   
35
+
35
36
  mybus = DBus.session_bus
36
37
  service = mybus['org.freedesktop.ScreenSaver']
37
- object = service.object '/ScreenSaver'
38
+ object = service['/ScreenSaver']
38
39
  object.introspect
39
40
  loop do
40
41
  object.SimulateUserActivity
@@ -43,20 +44,47 @@ is simply "dbus"
43
44
 
44
45
  ##### Retrieving Return Values
45
46
 
46
- A method proxy always returns an array of values. This is to
47
+ A method proxy simply returns a value.
48
+ In this example SuspendAllowed returns a boolean:
49
+
50
+ mybus = DBus.session_bus
51
+ pm_s = mybus['org.freedesktop.PowerManagement']
52
+ pm_o = pm_s['/org/freedesktop/PowerManagement']
53
+ pm_o.introspect
54
+ pm_i = pm_o['org.freedesktop.PowerManagement']
55
+
56
+ if pm_i.CanSuspend
57
+ pm_i.Suspend
58
+ end
59
+
60
+ ###### Multiple Return Values
61
+
62
+ In former versions of this library,
63
+ a method proxy always returned an array of values. This was to
47
64
  accomodate the rare cases of a DBus method specifying more than one
48
- *out* parameter. For nearly all methods you should use `Method[0]` or
65
+ *out* parameter. For compatibility, the behavior is preserved if you
66
+ construct a {DBus::ProxyObject} with {DBus::ApiOptions::A0},
67
+ which is what {DBus::Service#object} does.
68
+
69
+ For nearly all methods you used `Method[0]` or
49
70
  `Method.first`
50
71
  ([I#30](https://github.com/mvidner/ruby-dbus/issues/30)).
51
72
 
73
+ mybus = DBus.session_bus
74
+ pm_s = mybus['org.freedesktop.PowerManagement']
75
+ # use legacy compatibility API
76
+ pm_o = pm_s.object['/org/freedesktop/PowerManagement']
77
+ pm_o.introspect
78
+ pm_i = pm_o['org.freedesktop.PowerManagement']
79
+
52
80
  # wrong
53
- if upower_i.SuspendAllowed # [false] is true!
54
- upower_i.Suspend
55
- end
81
+ # if pm_i.CanSuspend
82
+ # pm_i.Suspend # [false] is true!
83
+ # end
56
84
 
57
85
  # right
58
- if upower_i.SuspendAllowed[0]
59
- upower_i.Suspend
86
+ if pm_i.CanSuspend[0]
87
+ pm_i.Suspend
60
88
  end
61
89
 
62
90
  #### Accessing Properties
@@ -68,7 +96,7 @@ an actual Hash of them.
68
96
 
69
97
  sysbus = DBus.system_bus
70
98
  upower_s = sysbus['org.freedesktop.UPower']
71
- upower_o = upower_s.object '/org/freedesktop/UPower'
99
+ upower_o = upower_s['/org/freedesktop/UPower']
72
100
  upower_o.introspect
73
101
  upower_i = upower_o['org.freedesktop.UPower']
74
102
 
@@ -112,6 +140,9 @@ To receive signals for a specific object and interface, use
112
140
  login_o.introspect
113
141
  login_o.default_iface = 'org.freedesktop.login1.Manager'
114
142
 
143
+ main = DBus::Main.new
144
+ main << sysbus
145
+
115
146
  # to trigger this signal, login on the Linux console
116
147
  login_o.on_signal("SessionNew") do |name, opath|
117
148
  puts "New session: #{name}"
@@ -121,10 +152,9 @@ To receive signals for a specific object and interface, use
121
152
  session_i = session_o['org.freedesktop.login1.Session']
122
153
  uid, user_opath = session_i['User']
123
154
  puts "Its UID: #{uid}"
155
+ main.quit
124
156
  end
125
157
 
126
- main = DBus::Main.new
127
- main << sysbus
128
158
  main.run
129
159
 
130
160
  ### Intermediate Concepts
@@ -174,7 +204,7 @@ If the signature expects a Variant
174
204
 
175
205
  If a byte array (`ay`) is expected you can pass a String too.
176
206
  The bytes sent are according to the string's
177
- [encoding](http://ruby-doc.org/core-1.9.3/Encoding.html).
207
+ [encoding](http://ruby-doc.org/core-2.0.0/Encoding.html).
178
208
 
179
209
  ##### nil
180
210
 
@@ -187,8 +217,11 @@ The bytes sent are according to the string's
187
217
  D-Bus calls can reply with an error instead of a return value. An error is
188
218
  translated to a Ruby exception, an instance of {DBus::Error}.
189
219
 
220
+ nm_o = DBus.system_bus["org.freedesktop.NetworkManager"]["/org/freedesktop/NetworkManager"]
221
+ nm_o.introspect
222
+ nm = nm_o["org.freedesktop.NetworkManager"]
190
223
  begin
191
- network_manager.sleep
224
+ nm.Sleep(false)
192
225
  rescue DBus::Error => e
193
226
  puts e unless e.name == "org.freedesktop.NetworkManager.AlreadyAsleepOrAwake"
194
227
  end
@@ -6,7 +6,7 @@
6
6
  # -- Arnaud
7
7
 
8
8
  require 'dbus'
9
- require 'libglade2'
9
+ require "gtk2"
10
10
 
11
11
  $enable_system = false
12
12
 
@@ -74,25 +74,26 @@ end
74
74
 
75
75
  class DBusUI
76
76
  def initialize
77
- @glade = GladeXML.new("gdbus.glade") { |h| method(h) } # This block is like
78
- # black magic :)
79
- @sessiontreeview = @glade.get_widget("sessiontreeview")
77
+ @glade = Gtk::Builder.new
78
+ @glade << "gdbus.glade"
79
+
80
+ @sessiontreeview = @glade.get_object("sessiontreeview")
80
81
  setup_treeview_renderer(@sessiontreeview, 'D-Bus Objects')
81
82
  @sessiontreeview.selection.signal_connect("changed") do |selection|
82
83
  on_treeview_selection_changed(selection)
83
84
  end
84
85
 
85
- @systemtreeview = @glade.get_widget("systemtreeview")
86
+ @systemtreeview = @glade.get_object("systemtreeview")
86
87
  setup_treeview_renderer(@systemtreeview, 'D-Bus Objects')
87
88
  @systemtreeview.selection.signal_connect("changed") do |selection|
88
89
  on_treeview_selection_changed(selection)
89
90
  end
90
91
 
91
- @methsigtreeview = @glade.get_widget("methsigtreeview")
92
+ @methsigtreeview = @glade.get_object("methsigtreeview")
92
93
  # ierk
93
94
  setup_methodview_renderer(@methsigtreeview)
94
95
 
95
- @window = @glade.get_widget("window1")
96
+ @window = @glade.get_object("window1")
96
97
  @window.show_all
97
98
  start_buses
98
99
  end
@@ -1,184 +1,98 @@
1
- <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2
- <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
3
-
4
- <glade-interface>
5
-
6
- <widget class="GtkWindow" id="window1">
7
- <property name="visible">True</property>
8
- <property name="title" translatable="yes">GD-Bus</property>
9
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
10
- <property name="window_position">GTK_WIN_POS_NONE</property>
11
- <property name="modal">False</property>
12
- <property name="default_width">500</property>
13
- <property name="default_height">400</property>
14
- <property name="resizable">True</property>
15
- <property name="destroy_with_parent">False</property>
16
- <property name="decorated">True</property>
17
- <property name="skip_taskbar_hint">False</property>
18
- <property name="skip_pager_hint">False</property>
19
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
20
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
21
- <property name="focus_on_map">True</property>
22
- <property name="urgency_hint">False</property>
23
- <signal name="delete_event" handler="on_window_delete_event" last_modification_time="Sat, 17 Mar 2007 14:49:13 GMT"/>
24
-
25
- <child>
26
- <widget class="GtkHPaned" id="hpaned1">
27
- <property name="visible">True</property>
28
- <property name="can_focus">True</property>
29
-
30
- <child>
31
- <widget class="GtkNotebook" id="notebook1">
32
- <property name="visible">True</property>
33
- <property name="can_focus">True</property>
34
- <property name="show_tabs">True</property>
35
- <property name="show_border">True</property>
36
- <property name="tab_pos">GTK_POS_TOP</property>
37
- <property name="scrollable">False</property>
38
- <property name="enable_popup">False</property>
39
-
40
- <child>
41
- <widget class="GtkScrolledWindow" id="scrolledwindow3">
42
- <property name="visible">True</property>
43
- <property name="can_focus">True</property>
44
- <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
45
- <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
46
- <property name="shadow_type">GTK_SHADOW_IN</property>
47
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
48
-
49
- <child>
50
- <widget class="GtkTreeView" id="sessiontreeview">
51
- <property name="visible">True</property>
52
- <property name="can_focus">True</property>
53
- <property name="headers_visible">True</property>
54
- <property name="rules_hint">False</property>
55
- <property name="reorderable">False</property>
56
- <property name="enable_search">True</property>
57
- <property name="fixed_height_mode">False</property>
58
- <property name="hover_selection">False</property>
59
- <property name="hover_expand">False</property>
60
- <signal name="row_activated" handler="on_sessiontreeview_row_activated" last_modification_time="Sat, 17 Mar 2007 10:17:11 GMT"/>
61
- </widget>
62
- </child>
63
- </widget>
64
- <packing>
65
- <property name="tab_expand">False</property>
66
- <property name="tab_fill">True</property>
67
- </packing>
68
- </child>
69
-
70
- <child>
71
- <widget class="GtkLabel" id="label1">
72
- <property name="visible">True</property>
73
- <property name="label" translatable="yes">Session</property>
74
- <property name="use_underline">False</property>
75
- <property name="use_markup">False</property>
76
- <property name="justify">GTK_JUSTIFY_LEFT</property>
77
- <property name="wrap">False</property>
78
- <property name="selectable">False</property>
79
- <property name="xalign">0.5</property>
80
- <property name="yalign">0.5</property>
81
- <property name="xpad">0</property>
82
- <property name="ypad">0</property>
83
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
84
- <property name="width_chars">-1</property>
85
- <property name="single_line_mode">False</property>
86
- <property name="angle">0</property>
87
- </widget>
88
- <packing>
89
- <property name="type">tab</property>
90
- </packing>
91
- </child>
92
-
93
- <child>
94
- <widget class="GtkScrolledWindow" id="scrolledwindow5">
95
- <property name="visible">True</property>
96
- <property name="can_focus">True</property>
97
- <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
98
- <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
99
- <property name="shadow_type">GTK_SHADOW_IN</property>
100
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
101
-
102
- <child>
103
- <widget class="GtkTreeView" id="systemtreeview">
104
- <property name="visible">True</property>
105
- <property name="can_focus">True</property>
106
- <property name="headers_visible">True</property>
107
- <property name="rules_hint">False</property>
108
- <property name="reorderable">False</property>
109
- <property name="enable_search">True</property>
110
- <property name="fixed_height_mode">False</property>
111
- <property name="hover_selection">False</property>
112
- <property name="hover_expand">False</property>
113
- </widget>
114
- </child>
115
- </widget>
116
- <packing>
117
- <property name="tab_expand">False</property>
118
- <property name="tab_fill">True</property>
119
- </packing>
120
- </child>
121
-
122
- <child>
123
- <widget class="GtkLabel" id="label2">
124
- <property name="visible">True</property>
125
- <property name="label" translatable="yes">System</property>
126
- <property name="use_underline">False</property>
127
- <property name="use_markup">False</property>
128
- <property name="justify">GTK_JUSTIFY_LEFT</property>
129
- <property name="wrap">False</property>
130
- <property name="selectable">False</property>
131
- <property name="xalign">0.5</property>
132
- <property name="yalign">0.5</property>
133
- <property name="xpad">0</property>
134
- <property name="ypad">0</property>
135
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
136
- <property name="width_chars">-1</property>
137
- <property name="single_line_mode">False</property>
138
- <property name="angle">0</property>
139
- </widget>
140
- <packing>
141
- <property name="type">tab</property>
142
- </packing>
143
- </child>
144
- </widget>
145
- <packing>
146
- <property name="shrink">True</property>
147
- <property name="resize">False</property>
148
- </packing>
149
- </child>
150
-
151
- <child>
152
- <widget class="GtkScrolledWindow" id="scrolledwindow4">
153
- <property name="visible">True</property>
154
- <property name="can_focus">True</property>
155
- <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
156
- <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
157
- <property name="shadow_type">GTK_SHADOW_IN</property>
158
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
159
-
160
- <child>
161
- <widget class="GtkTreeView" id="methsigtreeview">
162
- <property name="visible">True</property>
163
- <property name="can_focus">True</property>
164
- <property name="headers_visible">True</property>
165
- <property name="rules_hint">False</property>
166
- <property name="reorderable">False</property>
167
- <property name="enable_search">True</property>
168
- <property name="fixed_height_mode">False</property>
169
- <property name="hover_selection">False</property>
170
- <property name="hover_expand">False</property>
171
- <signal name="row_activated" handler="on_method_activated" last_modification_time="Sat, 17 Mar 2007 14:49:13 GMT"/>
172
- </widget>
173
- </child>
174
- </widget>
175
- <packing>
176
- <property name="shrink">True</property>
177
- <property name="resize">False</property>
178
- </packing>
179
- </child>
180
- </widget>
181
- </child>
182
- </widget>
183
-
184
- </glade-interface>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <interface>
3
+ <!-- interface-requires gtk+ 2.6 -->
4
+ <!-- interface-naming-policy toplevel-contextual -->
5
+ <object class="GtkWindow" id="window1">
6
+ <property name="visible">True</property>
7
+ <property name="can_focus">False</property>
8
+ <property name="title" translatable="yes">GD-Bus</property>
9
+ <property name="default_width">500</property>
10
+ <property name="default_height">400</property>
11
+ <signal name="delete-event" handler="on_window_delete_event" swapped="no"/>
12
+ <child>
13
+ <object class="GtkHPaned" id="hpaned1">
14
+ <property name="visible">True</property>
15
+ <property name="can_focus">True</property>
16
+ <child>
17
+ <object class="GtkNotebook" id="notebook1">
18
+ <property name="visible">True</property>
19
+ <property name="can_focus">True</property>
20
+ <child>
21
+ <object class="GtkScrolledWindow" id="scrolledwindow3">
22
+ <property name="visible">True</property>
23
+ <property name="can_focus">True</property>
24
+ <property name="shadow_type">in</property>
25
+ <child>
26
+ <object class="GtkTreeView" id="sessiontreeview">
27
+ <property name="visible">True</property>
28
+ <property name="can_focus">True</property>
29
+ <signal name="row-activated" handler="on_sessiontreeview_row_activated" swapped="no"/>
30
+ </object>
31
+ </child>
32
+ </object>
33
+ </child>
34
+ <child type="tab">
35
+ <object class="GtkLabel" id="label1">
36
+ <property name="visible">True</property>
37
+ <property name="can_focus">False</property>
38
+ <property name="label" translatable="yes">Session</property>
39
+ </object>
40
+ <packing>
41
+ <property name="tab_fill">False</property>
42
+ </packing>
43
+ </child>
44
+ <child>
45
+ <object class="GtkScrolledWindow" id="scrolledwindow5">
46
+ <property name="visible">True</property>
47
+ <property name="can_focus">True</property>
48
+ <property name="shadow_type">in</property>
49
+ <child>
50
+ <object class="GtkTreeView" id="systemtreeview">
51
+ <property name="visible">True</property>
52
+ <property name="can_focus">True</property>
53
+ </object>
54
+ </child>
55
+ </object>
56
+ <packing>
57
+ <property name="position">1</property>
58
+ </packing>
59
+ </child>
60
+ <child type="tab">
61
+ <object class="GtkLabel" id="label2">
62
+ <property name="visible">True</property>
63
+ <property name="can_focus">False</property>
64
+ <property name="label" translatable="yes">System</property>
65
+ </object>
66
+ <packing>
67
+ <property name="position">1</property>
68
+ <property name="tab_fill">False</property>
69
+ </packing>
70
+ </child>
71
+ </object>
72
+ <packing>
73
+ <property name="resize">False</property>
74
+ <property name="shrink">True</property>
75
+ </packing>
76
+ </child>
77
+ <child>
78
+ <object class="GtkScrolledWindow" id="scrolledwindow4">
79
+ <property name="visible">True</property>
80
+ <property name="can_focus">True</property>
81
+ <property name="shadow_type">in</property>
82
+ <child>
83
+ <object class="GtkTreeView" id="methsigtreeview">
84
+ <property name="visible">True</property>
85
+ <property name="can_focus">True</property>
86
+ <signal name="row-activated" handler="on_method_activated" swapped="no"/>
87
+ </object>
88
+ </child>
89
+ </object>
90
+ <packing>
91
+ <property name="resize">False</property>
92
+ <property name="shrink">True</property>
93
+ </packing>
94
+ </child>
95
+ </object>
96
+ </child>
97
+ </object>
98
+ </interface>
@@ -0,0 +1,19 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ # find the library without external help
4
+ $:.unshift File.expand_path("../../../lib", __FILE__)
5
+
6
+ require "dbus"
7
+
8
+ bus = DBus::SystemBus.instance
9
+ driver_svc = bus["org.freedesktop.DBus"]
10
+ # p driver_svc
11
+ driver_obj = driver_svc["/"]
12
+ # p driver_obj
13
+ driver_obj.introspect
14
+
15
+ driver_ifc = driver_obj["org.freedesktop.DBus"]
16
+ # p driver_ifc
17
+
18
+ bus_id = driver_ifc.GetId
19
+ puts "The system bus id is #{bus_id}"
@@ -8,6 +8,7 @@
8
8
  # License, version 2.1 as published by the Free Software Foundation.
9
9
  # See the file "COPYING" for the exact licensing terms.
10
10
 
11
+ require_relative "dbus/api_options"
11
12
  require_relative "dbus/auth"
12
13
  require_relative "dbus/bus"
13
14
  require_relative "dbus/core_ext/class/attribute"
@@ -0,0 +1,24 @@
1
+ # This file is part of the ruby-dbus project
2
+ # Copyright (C) 2016 Martin Vidner
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License, version 2.1 as published by the Free Software Foundation.
7
+ # See the file "COPYING" for the exact licensing terms.
8
+
9
+ module DBus
10
+ class ApiOptions
11
+ # https://github.com/mvidner/ruby-dbus/issues/30
12
+ attr_accessor :proxy_method_returns_array
13
+
14
+ A0 = ApiOptions.new
15
+ A0.proxy_method_returns_array = true
16
+ A0.freeze
17
+
18
+ A1 = ApiOptions.new
19
+ A1.proxy_method_returns_array = false
20
+ A1.freeze
21
+
22
+ CURRENT = A1
23
+ end
24
+ end
@@ -50,10 +50,20 @@ module DBus
50
50
 
51
51
  # Retrieves an object at the given _path_.
52
52
  # @return [ProxyObject]
53
- def object(path)
54
- node = get_node(path, true)
55
- if node.object.nil?
56
- node.object = ProxyObject.new(@bus, @name, path)
53
+ def [](path)
54
+ object(path, api: ApiOptions::A1)
55
+ end
56
+
57
+ # Retrieves an object at the given _path_
58
+ # whose methods always return an array.
59
+ # @return [ProxyObject]
60
+ def object(path, api: ApiOptions::A0)
61
+ node = get_node(path, _create = true)
62
+ if node.object.nil? || node.object.api != api
63
+ node.object = ProxyObject.new(
64
+ @bus, @name, path,
65
+ api: api
66
+ )
57
67
  end
58
68
  node.object
59
69
  end
@@ -417,12 +427,17 @@ module DBus
417
427
  end
418
428
 
419
429
  # Set up a ProxyObject for the bus itself, since the bus is introspectable.
430
+ # @return [ProxyObject] that always returns an array
431
+ # ({DBus::ApiOptions#proxy_method_returns_array})
420
432
  # Returns the object.
421
433
  def proxy
422
434
  if @proxy == nil
423
435
  path = "/org/freedesktop/DBus"
424
436
  dest = "org.freedesktop.DBus"
425
- pof = DBus::ProxyObjectFactory.new(DBUSXMLINTRO, self, dest, path)
437
+ pof = DBus::ProxyObjectFactory.new(
438
+ DBUSXMLINTRO, self, dest, path,
439
+ api: ApiOptions::A0
440
+ )
426
441
  @proxy = pof.build["org.freedesktop.DBus"]
427
442
  end
428
443
  @proxy
@@ -27,13 +27,17 @@ module DBus
27
27
  attr_reader :bus
28
28
  # @return [String] The name of the default interface of the object.
29
29
  attr_accessor :default_iface
30
+ # @api private
31
+ # @return [ApiOptions]
32
+ attr_reader :api
30
33
 
31
34
  # Creates a new proxy object living on the given _bus_ at destination _dest_
32
35
  # on the given _path_.
33
- def initialize(bus, dest, path)
36
+ def initialize(bus, dest, path, api: ApiOptions::CURRENT)
34
37
  @bus, @destination, @path = bus, dest, path
35
38
  @interfaces = Hash.new
36
39
  @subnodes = Array.new
40
+ @api = api
37
41
  end
38
42
 
39
43
  # Returns the interfaces of the object.
@@ -140,10 +144,5 @@ module DBus
140
144
  raise NoMethodError, "undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
141
145
  end
142
146
  end
143
-
144
- # Returns the singleton class of the object.
145
- def singleton_class
146
- (class << self ; self ; end)
147
- end
148
147
  end # class ProxyObject
149
148
  end
@@ -14,8 +14,9 @@ module DBus
14
14
  class ProxyObjectFactory
15
15
  # Creates a new proxy object factory for the given introspection XML _xml_,
16
16
  # _bus_, destination _dest_, and _path_.
17
- def initialize(xml, bus, dest, path)
17
+ def initialize(xml, bus, dest, path, api: ApiOptions::CURRENT)
18
18
  @xml, @bus, @path, @dest = xml, bus, path, dest
19
+ @api = api
19
20
  end
20
21
 
21
22
  # Investigates the sub-nodes of the proxy object _po_ based on the
@@ -33,7 +34,7 @@ module DBus
33
34
 
34
35
  # Generates, sets up and returns the proxy object.
35
36
  def build
36
- po = ProxyObject.new(@bus, @dest, @path)
37
+ po = ProxyObject.new(@bus, @dest, @path, api: @api)
37
38
  ProxyObjectFactory.introspect_into(po, @xml)
38
39
  po
39
40
  end
@@ -34,11 +34,6 @@ module DBus
34
34
  @name
35
35
  end
36
36
 
37
- # Returns the singleton class of the interface.
38
- def singleton_class
39
- (class << self ; self ; end)
40
- end
41
-
42
37
  # Defines a method on the interface from the Method descriptor _m_.
43
38
  def define_method_from_descriptor(m)
44
39
  m.params.each do |fpar|
@@ -63,7 +58,12 @@ module DBus
63
58
  par = fpar.type
64
59
  msg.add_param(par, args.shift)
65
60
  end
66
- @object.bus.send_sync_or_async(msg, &reply_handler)
61
+ ret = @object.bus.send_sync_or_async(msg, &reply_handler)
62
+ if ret.nil? || @object.api.proxy_method_returns_array
63
+ ret
64
+ else
65
+ m.rets.size == 1 ? ret.first : ret
66
+ end
67
67
  end
68
68
  end
69
69
 
@@ -110,11 +110,20 @@ module DBus
110
110
  PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
111
111
 
112
112
  # Read a property.
113
+ # @param propname [String]
113
114
  def [](propname)
114
- self.object[PROPERTY_INTERFACE].Get(self.name, propname)[0]
115
+ ret = self.object[PROPERTY_INTERFACE].Get(self.name, propname)
116
+ # this method always returns the single property
117
+ if @object.api.proxy_method_returns_array
118
+ ret[0]
119
+ else
120
+ ret
121
+ end
115
122
  end
116
123
 
117
124
  # Write a property.
125
+ # @param propname [String]
126
+ # @param value [Object]
118
127
  def []=(propname, value)
119
128
  self.object[PROPERTY_INTERFACE].Set(self.name, propname, value)
120
129
  end
@@ -122,7 +131,13 @@ module DBus
122
131
  # Read all properties at once, as a hash.
123
132
  # @return [Hash{String}]
124
133
  def all_properties
125
- self.object[PROPERTY_INTERFACE].GetAll(self.name)[0]
134
+ ret = self.object[PROPERTY_INTERFACE].GetAll(self.name)
135
+ # this method always returns the single property
136
+ if @object.api.proxy_method_returns_array
137
+ ret[0]
138
+ else
139
+ ret
140
+ end
126
141
  end
127
142
  end # class ProxyObjectInterface
128
143
  end
@@ -14,7 +14,7 @@ GEMSPEC = Gem::Specification.new do |s|
14
14
  s.homepage = "https://trac.luon.net/ruby-dbus"
15
15
  s.files = FileList["{doc,examples,lib,spec}/**/*", "COPYING", "NEWS", "Rakefile", "README.md", "ruby-dbus.gemspec", "VERSION", ".rspec"].to_a.sort
16
16
  s.require_path = "lib"
17
- s.required_ruby_version = ">= 1.9.3"
17
+ s.required_ruby_version = ">= 2.0.0"
18
18
  s.add_development_dependency("packaging_rake_tasks")
19
19
  s.add_development_dependency("rspec")
20
20
  end
@@ -5,8 +5,8 @@ require "dbus"
5
5
  describe "PropertyTest" do
6
6
  before(:each) do
7
7
  session_bus = DBus::ASessionBus.new
8
- svc = session_bus.service("org.ruby.service")
9
- @obj = svc.object("/org/ruby/MyInstance")
8
+ @svc = session_bus.service("org.ruby.service")
9
+ @obj = @svc.object("/org/ruby/MyInstance")
10
10
  @obj.introspect
11
11
  @iface = @obj["org.ruby.SampleInterface"]
12
12
  end
@@ -15,6 +15,14 @@ describe "PropertyTest" do
15
15
  expect(@iface["ReadMe"]).to eq("READ ME")
16
16
  end
17
17
 
18
+ it "tests property reading on a V1 object" do
19
+ obj = @svc["/org/ruby/MyInstance"]
20
+ obj.introspect
21
+ iface = obj["org.ruby.SampleInterface"]
22
+
23
+ expect(iface["ReadMe"]).to eq("READ ME")
24
+ end
25
+
18
26
  it "tests property nonreading" do
19
27
  expect { @iface["WriteMe"] }.to raise_error(DBus::Error, /not readable/)
20
28
  end
@@ -43,6 +51,15 @@ describe "PropertyTest" do
43
51
  expect(all.keys.sort).to eq(["ReadMe", "ReadOrWriteMe"])
44
52
  end
45
53
 
54
+ it "tests get all on a V1 object" do
55
+ obj = @svc["/org/ruby/MyInstance"]
56
+ obj.introspect
57
+ iface = obj["org.ruby.SampleInterface"]
58
+
59
+ all = iface.all_properties
60
+ expect(all.keys.sort).to eq(["ReadMe", "ReadOrWriteMe"])
61
+ end
62
+
46
63
  it "tests unknown property reading" do
47
64
  expect { @iface["Spoon"] }.to raise_error(DBus::Error, /not found/)
48
65
  end
@@ -6,8 +6,8 @@ require "dbus"
6
6
  describe "ValueTest" do
7
7
  before(:each) do
8
8
  session_bus = DBus::ASessionBus.new
9
- svc = session_bus.service("org.ruby.service")
10
- @obj = svc.object("/org/ruby/MyInstance")
9
+ @svc = session_bus.service("org.ruby.service")
10
+ @obj = @svc.object("/org/ruby/MyInstance")
11
11
  @obj.introspect # necessary
12
12
  @obj.default_iface = "org.ruby.SampleInterface"
13
13
  end
@@ -36,7 +36,19 @@ describe "ValueTest" do
36
36
  empty_hash = {}
37
37
  expect(@obj.bounce_variant(empty_hash)[0]).to eq(empty_hash)
38
38
  end
39
-
39
+
40
+ it "retrieves a single return value with API V1" do
41
+ obj = @svc["/org/ruby/MyInstance"]
42
+ obj.introspect
43
+ obj.default_iface = "org.ruby.SampleInterface"
44
+
45
+ expect(obj.bounce_variant("cuckoo")).to eq("cuckoo")
46
+ expect(obj.bounce_variant(["coucou", "kuku"])).to eq(["coucou", "kuku"])
47
+ expect(obj.bounce_variant([])).to eq([])
48
+ empty_hash = {}
49
+ expect(obj.bounce_variant(empty_hash)).to eq(empty_hash)
50
+ end
51
+
40
52
  # these are ambiguous
41
53
  it "tests pairs with a string" do
42
54
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-dbus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruby DBus Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-11 00:00:00.000000000 Z
11
+ date: 2016-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: packaging_rake_tasks
@@ -63,10 +63,12 @@ files:
63
63
  - examples/service/call_service.rb
64
64
  - examples/service/service_newapi.rb
65
65
  - examples/simple/call_introspect.rb
66
+ - examples/simple/get_id.rb
66
67
  - examples/simple/properties.rb
67
68
  - examples/utils/listnames.rb
68
69
  - examples/utils/notify.rb
69
70
  - lib/dbus.rb
71
+ - lib/dbus/api_options.rb
70
72
  - lib/dbus/auth.rb
71
73
  - lib/dbus/bus.rb
72
74
  - lib/dbus/core_ext/array/extract_options.rb
@@ -125,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
127
  requirements:
126
128
  - - ">="
127
129
  - !ruby/object:Gem::Version
128
- version: 1.9.3
130
+ version: 2.0.0
129
131
  required_rubygems_version: !ruby/object:Gem::Requirement
130
132
  requirements:
131
133
  - - ">="