Merge lp:~tombeckmann/pantheon-plugs/gcc-get-toplevel-fix into lp:~elementary-apps/pantheon-plugs/dynamic-gcc-plug-freya

Proposed by Tom Beckmann
Status: Merged
Approved by: Corentin Noël
Approved revision: 48
Merged at revision: 44
Proposed branch: lp:~tombeckmann/pantheon-plugs/gcc-get-toplevel-fix
Merge into: lp:~elementary-apps/pantheon-plugs/dynamic-gcc-plug-freya
Diff against target: 443 lines (+265/-8)
7 files modified
CMakeLists.txt (+5/-2)
libgnome-control-center/cc-gnome_cc-panel.c (+8/-2)
libgnome-control-center/switchboard-shell.c (+136/-0)
libgnome-control-center/switchboard-shell.h (+61/-0)
plugs/Mouse/MousePlug.vala (+22/-2)
plugs/Network/NetworkPlug.vala (+24/-2)
vapi/SwitchboardShell.vapi (+9/-0)
To merge this branch: bzr merge lp:~tombeckmann/pantheon-plugs/gcc-get-toplevel-fix
Reviewer Review Type Date Requested Status
Corentin Noël Approve
Review via email: mp+225752@code.launchpad.net

Commit message

Fix crash when cc_shell_get_toplevel is called from a panel.
Put embedded widgets in an actionbar.

Description of the change

This fixes https://bugs.launchpad.net/switchboard/+bug/1305618 by implementing a shell object properly. We should check if there is value in implementing cc_shell_embed_widget_in_header too, it is apparently called by panels, but I haven't checked yet what they try to embed.

To post a comment you must log in.
Revision history for this message
Tom Beckmann (tombeckmann) wrote :

Checked it now, we should definitely implement it. There are two panels using the function. The network one provides its airplane mode via this function and the mouse one its test area.

45. By Tom Beckmann

make things work when a plug is opened a second time, implement embed_widget

46. By Tom Beckmann

some cleanup

47. By Tom Beckmann

put embedded widgets in an actionbar instead of the header

48. By Tom Beckmann

get toplevel via our panel instance

Revision history for this message
Tom Beckmann (tombeckmann) wrote :

This branch no longer requires API changes in switchboard, it gets all the necessary data itself and embeds widgets in an action bar at the bottom.
I hope it can be accepted now.

Revision history for this message
Corentin Noël (tintou) wrote :

This branch is really a nice fix!
While I'm not a C expert, all what I see here is fine. Great work!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-04-24 22:26:52 +0000
3+++ CMakeLists.txt 2014-07-07 22:24:10 +0000
4@@ -34,6 +34,7 @@
5 set (VALAC_MAIN_OPTIONS
6 --thread
7 --vapidir=${CMAKE_SOURCE_DIR}/vapi
8+ --pkg SwitchboardShell
9 )
10
11 set (DEPS_PACKAGES
12@@ -50,6 +51,7 @@
13 granite
14 gnome-desktop-3.0
15 libgnome-control-center
16+ switchboard-2.0
17 )
18
19 # Add all your dependencies to the list below
20@@ -70,10 +72,11 @@
21 install (FILES ${desktops} DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications")
22
23 set (C_FILES
24- ${CMAKE_CURRENT_SOURCE_DIR}/libgnome-control-center/cc-gnome_cc-panel.c)
25+ ${CMAKE_CURRENT_SOURCE_DIR}/libgnome-control-center/cc-gnome_cc-panel.c
26+ ${CMAKE_CURRENT_SOURCE_DIR}/libgnome-control-center/switchboard-shell.c)
27
28 # Traslation stuff
29 add_subdirectory (po)
30
31 # Plugs
32-add_subdirectory(plugs)
33\ No newline at end of file
34+add_subdirectory(plugs)
35
36=== modified file 'libgnome-control-center/cc-gnome_cc-panel.c'
37--- libgnome-control-center/cc-gnome_cc-panel.c 2014-01-14 16:26:18 +0000
38+++ libgnome-control-center/cc-gnome_cc-panel.c 2014-07-07 22:24:10 +0000
39@@ -24,6 +24,7 @@
40 #include <stdlib.h>
41 #include <sys/wait.h>
42
43+#include "switchboard-shell.h"
44 #include "cc-gnome_cc-panel.h"
45 #include <libgnome-control-center/cc-shell.h>
46
47@@ -38,6 +39,8 @@
48 struct _CcGnomeCCPanelPrivate
49 {
50 GIOExtensionPoint* extension_point;
51+
52+ SwitchboardShell *shell;
53 };
54
55 typedef struct
56@@ -127,7 +130,10 @@
57 static void
58 cc_gnome_cc_panel_init (CcGnomeCCPanel *self)
59 {
60+ self->priv = GNOME_CC_PANEL_PRIVATE (self);
61+ self->priv->shell = g_object_ref (switchboard_shell_new ());
62 }
63+
64 gchar* gccname;
65 static GObject *
66 cc_gnome_cc_panel_constructor (GType gtype,
67@@ -136,7 +142,7 @@
68 {
69 GObjectClass* obj = G_OBJECT_CLASS (cc_gnome_cc_panel_parent_class)->constructor (gtype, n_properties, properties);
70 CcGnomeCCPanel* self = CC_GNOME_CC_PANEL (obj);
71- self->priv = GNOME_CC_PANEL_PRIVATE (self);
72+
73 g_type_from_name ("CcPanel");
74 self->priv->extension_point = g_io_extension_point_register (BUILD_CC_SHELL_PANEL_EXTENSION_POINT);
75 GList* l;
76@@ -166,7 +172,7 @@
77 GtkWidget *panel;
78
79 /* create the panel plugin */
80- panel = g_object_new (panel_type, NULL);//, "shell", self, NULL);
81+ panel = g_object_new (panel_type, "shell", self->priv->shell, NULL);
82
83 gtk_container_add(self, panel);
84 }
85
86=== added file 'libgnome-control-center/switchboard-shell.c'
87--- libgnome-control-center/switchboard-shell.c 1970-01-01 00:00:00 +0000
88+++ libgnome-control-center/switchboard-shell.c 2014-07-07 22:24:10 +0000
89@@ -0,0 +1,136 @@
90+//
91+// Copyright (C) 2014 Tom Beckmann
92+//
93+// This program is free software: you can redistribute it and/or modify
94+// it under the terms of the GNU General Public License as published by
95+// the Free Software Foundation, either version 3 of the License, or
96+// (at your option) any later version.
97+//
98+// This program is distributed in the hope that it will be useful,
99+// but WITHOUT ANY WARRANTY; without even the implied warranty of
100+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
101+// GNU General Public License for more details.
102+//
103+// You should have received a copy of the GNU General Public License
104+// along with this program. If not, see <http://www.gnu.org/licenses/>.
105+//
106+
107+#include "switchboard-shell.h"
108+
109+G_DEFINE_TYPE (SwitchboardShell, switchboard_shell, CC_TYPE_SHELL)
110+
111+static void
112+_shell_set_active_panel_from_id (CcShell *shell, const gchar **start_id,
113+ const gchar **argv, GError **error)
114+{
115+ // FIXME do we need this?
116+}
117+
118+static void
119+_shell_embed_widget_in_header (CcShell *shell, GtkWidget *widget)
120+{
121+ g_signal_emit_by_name (shell, "embed-widget-requested", widget);
122+}
123+
124+static GtkWidget *
125+_shell_get_toplevel (CcShell *shell)
126+{
127+ GtkWidget *toplevel;
128+
129+ g_signal_emit_by_name (shell, "get-toplevel-requested", &toplevel);
130+ if (!toplevel)
131+ g_critical ("plug did not connect to get-toplevel-requested signal, may cause a crash");
132+
133+ return toplevel;
134+}
135+
136+static void
137+switchboard_shell_get_property (GObject *object,
138+ guint property_id,
139+ GValue *value,
140+ GParamSpec *pspec)
141+{
142+ SwitchboardShellPrivate *priv = SWITCHBOARD_SHELL (object)->priv;
143+
144+ switch (property_id) {
145+ default:
146+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
147+ }
148+}
149+
150+static void
151+switchboard_shell_set_property (GObject *object,
152+ guint property_id,
153+ const GValue *value,
154+ GParamSpec *pspec)
155+{
156+ SwitchboardShellPrivate *priv = SWITCHBOARD_SHELL (object)->priv;
157+
158+ switch (property_id) {
159+ default:
160+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
161+ }
162+}
163+
164+static void
165+switchboard_shell_dispose (GObject *object)
166+{
167+ SwitchboardShellPrivate *priv = SWITCHBOARD_SHELL (object)->priv;
168+
169+ G_OBJECT_CLASS (switchboard_shell_parent_class)->dispose (object);
170+}
171+
172+static void
173+switchboard_shell_finalize (GObject *object)
174+{
175+ SwitchboardShellPrivate *priv = SWITCHBOARD_SHELL (object)->priv;
176+
177+ G_OBJECT_CLASS (switchboard_shell_parent_class)->finalize (object);
178+}
179+
180+
181+static void
182+switchboard_shell_class_init (SwitchboardShellClass *klass)
183+{
184+ GParamSpec *pspec;
185+
186+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
187+ CcShellClass *shell_class = CC_SHELL_CLASS (klass);
188+
189+ object_class->get_property = switchboard_shell_get_property;
190+ object_class->set_property = switchboard_shell_set_property;
191+ object_class->dispose = switchboard_shell_dispose;
192+ object_class->finalize = switchboard_shell_finalize;
193+
194+ shell_class->set_active_panel_from_id = _shell_set_active_panel_from_id;
195+ shell_class->embed_widget_in_header = _shell_embed_widget_in_header;
196+ shell_class->get_toplevel = _shell_get_toplevel;
197+
198+ g_signal_new ("embed-widget-requested",
199+ G_TYPE_FROM_CLASS (klass),
200+ G_SIGNAL_RUN_LAST,
201+ 0,
202+ NULL, NULL, NULL,
203+ G_TYPE_NONE,
204+ 1, GTK_TYPE_WIDGET);
205+
206+ g_signal_new ("get-toplevel-requested",
207+ G_TYPE_FROM_CLASS (klass),
208+ G_SIGNAL_RUN_LAST,
209+ 0,
210+ NULL, NULL, NULL,
211+ GTK_TYPE_WIDGET,
212+ 0);
213+}
214+
215+static void
216+switchboard_shell_init (SwitchboardShell *self)
217+{
218+}
219+
220+SwitchboardShell *
221+switchboard_shell_new ()
222+{
223+ return g_object_new (SWITCHBOARD_TYPE_SHELL, NULL);
224+}
225+
226
227=== added file 'libgnome-control-center/switchboard-shell.h'
228--- libgnome-control-center/switchboard-shell.h 1970-01-01 00:00:00 +0000
229+++ libgnome-control-center/switchboard-shell.h 2014-07-07 22:24:10 +0000
230@@ -0,0 +1,61 @@
231+//
232+// Copyright (C) 2014 Tom Beckmann
233+//
234+// This program is free software: you can redistribute it and/or modify
235+// it under the terms of the GNU General Public License as published by
236+// the Free Software Foundation, either version 3 of the License, or
237+// (at your option) any later version.
238+//
239+// This program is distributed in the hope that it will be useful,
240+// but WITHOUT ANY WARRANTY; without even the implied warranty of
241+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
242+// GNU General Public License for more details.
243+//
244+// You should have received a copy of the GNU General Public License
245+// along with this program. If not, see <http://www.gnu.org/licenses/>.
246+//
247+
248+#ifndef __SWITCHBOARD_SHELL_H__
249+#define __SWITCHBOARD_SHELL_H__
250+
251+#include <glib-object.h>
252+#include <libgnome-control-center/cc-shell.h>
253+#include <switchboard.h>
254+
255+G_BEGIN_DECLS
256+
257+#define SWITCHBOARD_TYPE_SHELL switchboard_shell_get_type()
258+#define SWITCHBOARD_SHELL(obj) \
259+ G_TYPE_CHECK_INSTANCE_CAST((obj), SWITCHBOARD_TYPE_SHELL, SwitchboardShell)
260+#define SWITCHBOARD_IS_SHELL(obj) \
261+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), SWITCHBOARD_TYPE_SHELL))
262+
263+#define SWITCHBOARD_IS_SHELL_CLASS(klass) \
264+ (G_TYPE_CHECK_CLASS_TYPE((klass), SWITCHBOARD_TYPE_SHELL))
265+
266+#define SWITCHBOARD_SHELL_GET_CLASS(obj) \
267+ (G_TYPE_INSTANCE_GET_CLASS((obj), SWITCHBOARD_TYPE_SHELL, SwitchboardShellClass))
268+
269+typedef struct _SwitchboardShell SwitchboardShell;
270+typedef struct _SwitchboardShellClass SwitchboardShellClass;
271+typedef struct _SwitchboardShellPrivate SwitchboardShellPrivate;
272+
273+struct _SwitchboardShell
274+{
275+ CcShell parent;
276+
277+ SwitchboardShellPrivate *priv;
278+};
279+
280+struct _SwitchboardShellClass
281+{
282+ CcShellClass parent_class;
283+};
284+
285+GType switchboard_shell_get_type (void) G_GNUC_CONST;
286+
287+SwitchboardShell *switchboard_shell_new ();
288+
289+G_END_DECLS
290+
291+#endif // __SWITCHBOARD_SHELL_H__
292
293=== modified file 'plugs/Mouse/MousePlug.vala'
294--- plugs/Mouse/MousePlug.vala 2014-04-14 17:14:38 +0000
295+++ plugs/Mouse/MousePlug.vala 2014-07-07 22:24:10 +0000
296@@ -25,6 +25,9 @@
297 private Cc.Panel panel;
298 private Gtk.Grid main_grid;
299 private Gtk.InfoBar infobar;
300+ private Gtk.ActionBar action_bar;
301+
302+ SwitchboardShell shell;
303
304 public Plug () {
305 Object (category: Category.HARDWARE,
306@@ -32,6 +35,9 @@
307 display_name: GLib.dgettext ("gnome-control-center-2.0", "Mouse & Touchpad"),
308 description: GLib.dgettext ("gnome-control-center-2.0", "Set your mouse and touchpad preferences"),
309 icon: "preferences-desktop-peripherals");
310+
311+ shell = new SwitchboardShell ();
312+ shell.embed_widget_requested.connect (embed_widget);
313 }
314
315 public override Gtk.Widget get_widget () {
316@@ -45,12 +51,16 @@
317 public override void shown () {
318 gccname = "mouse";
319 GLib.Intl.textdomain ("gnome-control-center-2.0");
320+
321 if (GLib.Type.from_name ("CcMousePanel") == 0) {
322 panel = Object.new(typeof(Cc.GnomeCCPanel)) as Cc.Panel;
323+ var shell = ((Cc.Panel) panel.get_children ().data).get_shell () as SwitchboardShell;
324+ shell.embed_widget_requested.connect (embed_widget);
325 } else {
326- panel = Object.new(GLib.Type.from_name ("CcMousePanel")) as Cc.Panel;
327+ panel = Object.new(GLib.Type.from_name ("CcMousePanel"), "shell", shell.@ref (), null) as Cc.Panel;
328 }
329 panel.expand = true;
330+
331 var permission = panel.get_permission();
332 if(permission != null) {
333 infobar = new Gtk.InfoBar ();
334@@ -66,8 +76,18 @@
335 infobar.no_show_all = true;
336 }
337 }
338+
339+ action_bar = new Gtk.ActionBar ();
340+
341 main_grid.attach (panel, 0, 1, 1, 1);
342 main_grid.show_all ();
343+ main_grid.attach (action_bar, 0, 2, 1, 1);
344+ }
345+
346+ void embed_widget (Gtk.Widget widget) {
347+ widget.margin_top = widget.margin_bottom = 6;
348+ action_bar.pack_end (widget);
349+ action_bar.show_all ();
350 }
351
352 public override void hidden () {
353@@ -92,4 +112,4 @@
354 debug ("Activating Mouse plug");
355 var plug = new GCC.Mouse.Plug ();
356 return plug;
357-}
358\ No newline at end of file
359+}
360
361=== modified file 'plugs/Network/NetworkPlug.vala'
362--- plugs/Network/NetworkPlug.vala 2014-04-14 17:14:38 +0000
363+++ plugs/Network/NetworkPlug.vala 2014-07-07 22:24:10 +0000
364@@ -25,6 +25,9 @@
365 private Gtk.Grid main_grid;
366 private Cc.Panel panel;
367 private Gtk.InfoBar infobar;
368+ private Gtk.ActionBar action_bar;
369+
370+ SwitchboardShell shell;
371
372 public Plug () {
373 Object (category: Category.NETWORK,
374@@ -32,6 +35,10 @@
375 display_name: GLib.dgettext ("gnome-control-center-2.0", "Network"),
376 description: GLib.dgettext ("gnome-control-center-2.0", "Network settings"),
377 icon: "preferences-system-network");
378+
379+ shell = new SwitchboardShell ();
380+ shell.embed_widget_requested.connect (embed_widget);
381+ shell.get_toplevel_requested.connect (() => panel.get_toplevel ());
382 }
383
384 public override Gtk.Widget get_widget () {
385@@ -45,12 +52,17 @@
386 public override void shown () {
387 gccname = "network";
388 GLib.Intl.textdomain ("gnome-control-center-2.0");
389+
390 if (GLib.Type.from_name ("CcNetworkPanel") == 0) {
391 panel = Object.new(typeof(Cc.GnomeCCPanel)) as Cc.Panel;
392+ var shell = (SwitchboardShell) ((Cc.Panel) panel.get_children ().data).get_shell ();
393+ shell.embed_widget_requested.connect (embed_widget);
394+ shell.get_toplevel_requested.connect (() => panel.get_toplevel ());
395 } else {
396- panel = Object.new(GLib.Type.from_name ("CcNetworkPanel")) as Cc.Panel;
397+ panel = Object.new(GLib.Type.from_name ("CcNetworkPanel"), "shell", shell.@ref (), null) as Cc.Panel;
398 }
399 panel.expand = true;
400+
401 var permission = panel.get_permission();
402 if(permission != null) {
403 infobar = new Gtk.InfoBar ();
404@@ -66,8 +78,18 @@
405 infobar.no_show_all = true;
406 }
407 }
408+
409+ action_bar = new Gtk.ActionBar ();
410+
411 main_grid.attach (panel, 0, 1, 1, 1);
412 main_grid.show_all ();
413+ main_grid.attach (action_bar, 0, 2, 1, 1);
414+ }
415+
416+ void embed_widget (Gtk.Widget widget) {
417+ widget.margin_top = widget.margin_bottom = 6;
418+ action_bar.pack_end (widget);
419+ action_bar.show_all ();
420 }
421
422 public override void hidden () {
423@@ -92,4 +114,4 @@
424 debug ("Activating Network plug");
425 var plug = new GCC.Network.Plug ();
426 return plug;
427-}
428\ No newline at end of file
429+}
430
431=== added file 'vapi/SwitchboardShell.vapi'
432--- vapi/SwitchboardShell.vapi 1970-01-01 00:00:00 +0000
433+++ vapi/SwitchboardShell.vapi 2014-07-07 22:24:10 +0000
434@@ -0,0 +1,9 @@
435+
436+[CCode (cheader_filename = "switchboard-shell.h", type_id = "switchboard_shell_get_type ()")]
437+public class SwitchboardShell : Cc.Shell
438+{
439+ public SwitchboardShell ();
440+ public signal void embed_widget_requested (Gtk.Widget widget);
441+ public signal void get_toplevel_requested ();
442+}
443+

Subscribers

People subscribed via source and target branches