ruby-dbus 0.11.2 → 0.12.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 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
  - - ">="