1 /*
2  * Copyright (c) 2005-2007 Jasper Huijsmans <jasper@xfce.org>
3  * Copyright (c) 2007-2010 Nick Schermer <nick@xfce.org>
4  *
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 #ifdef HAVE_MATH_H
25 #include <math.h>
26 #endif
27 
28 #include <gtk/gtk.h>
29 #include <libxfce4panel/libxfce4panel.h>
30 #include <libxfce4util/libxfce4util.h>
31 #include <libxfce4ui/libxfce4ui.h>
32 #include <common/panel-xfconf.h>
33 #include <common/panel-utils.h>
34 #include <common/panel-private.h>
35 #include <common/panel-debug.h>
36 #include <libwnck/libwnck.h>
37 
38 #include "pager.h"
39 #include "pager-buttons.h"
40 #include "pager-dialog_ui.h"
41 
42 
43 
44 #define WORKSPACE_SETTINGS_COMMAND "xfwm4-workspace-settings"
45 
46 
47 
48 static void     pager_plugin_get_property                 (GObject           *object,
49                                                            guint              prop_id,
50                                                            GValue            *value,
51                                                            GParamSpec        *pspec);
52 static void     pager_plugin_set_property                 (GObject           *object,
53                                                            guint              prop_id,
54                                                            const GValue      *value,
55                                                            GParamSpec        *pspec);
56 static gboolean pager_plugin_scroll_event                 (GtkWidget         *widget,
57                                                            GdkEventScroll    *event);
58 static void     pager_plugin_drag_begin_event             (GtkWidget         *widget,
59                                                            GdkDragContext    *context,
60                                                            gpointer           user_data);
61 static void     pager_plugin_drag_end_event               (GtkWidget         *widget,
62                                                            GdkDragContext    *context,
63                                                            gpointer           user_data);
64 static void     pager_plugin_screen_changed               (GtkWidget         *widget,
65                                                            GdkScreen         *previous_screen);
66 static void     pager_plugin_construct                    (XfcePanelPlugin   *panel_plugin);
67 static void     pager_plugin_style_updated                (GtkWidget         *pager,
68                                                            gpointer           user_data);
69 static void     pager_plugin_free_data                    (XfcePanelPlugin   *panel_plugin);
70 static gboolean pager_plugin_size_changed                 (XfcePanelPlugin   *panel_plugin,
71                                                            gint               size);
72 static void     pager_plugin_mode_changed                 (XfcePanelPlugin     *panel_plugin,
73                                                            XfcePanelPluginMode  mode);
74 static void     pager_plugin_configure_workspace_settings (GtkWidget         *button);
75 static void     pager_plugin_configure_plugin             (XfcePanelPlugin   *panel_plugin);
76 static void     pager_plugin_screen_layout_changed        (PagerPlugin       *plugin);
77 static void     pager_plugin_get_preferred_width          (GtkWidget           *widget,
78                                                            gint                *minimum_width,
79                                                            gint                *natural_width);
80 static void     pager_plugin_get_preferred_height         (GtkWidget           *widget,
81                                                            gint                *minimum_height,
82                                                            gint                *natural_height);
83 static void     pager_plugin_get_preferred_width_for_height (GtkWidget           *widget,
84                                                              gint                 height,
85                                                              gint                *minimum_width,
86                                                              gint                *natural_width);
87 static void     pager_plugin_get_preferred_height_for_width (GtkWidget           *widget,
88                                                              gint                 width,
89                                                              gint                *minimum_height,
90                                                              gint                *natural_height);
91 
92 
93 
94 struct _PagerPluginClass
95 {
96   XfcePanelPluginClass __parent__;
97 };
98 
99 struct _PagerPlugin
100 {
101   XfcePanelPlugin __parent__;
102 
103   GtkWidget     *pager;
104   GObject       *numbering_switch;
105   GObject       *numbering_label;
106   GObject       *scrolling_switch;
107   GObject       *scrolling_label;
108 
109   WnckScreen    *wnck_screen;
110 
111   /* settings */
112   guint          scrolling : 1;
113   guint          wrap_workspaces : 1;
114   guint          miniature_view : 1;
115   gint           rows;
116   gboolean       numbering;
117   gfloat         ratio;
118 };
119 
120 enum
121 {
122   PROP_0,
123   PROP_WORKSPACE_SCROLLING,
124   PROP_WRAP_WORKSPACES,
125   PROP_MINIATURE_VIEW,
126   PROP_ROWS,
127   PROP_NUMBERING
128 };
129 
130 
131 
132 /* define the plugin */
XFCE_PANEL_DEFINE_PLUGIN_RESIDENT(PagerPlugin,pager_plugin,pager_buttons_register_type)133 XFCE_PANEL_DEFINE_PLUGIN_RESIDENT (PagerPlugin, pager_plugin,
134     pager_buttons_register_type)
135 
136 
137 
138 static void
139 pager_plugin_class_init (PagerPluginClass *klass)
140 {
141   XfcePanelPluginClass *plugin_class;
142   GObjectClass         *gobject_class;
143   GtkWidgetClass       *widget_class;
144 
145   gobject_class = G_OBJECT_CLASS (klass);
146   gobject_class->get_property = pager_plugin_get_property;
147   gobject_class->set_property = pager_plugin_set_property;
148 
149   widget_class = GTK_WIDGET_CLASS (klass);
150   widget_class->scroll_event = pager_plugin_scroll_event;
151   widget_class->get_preferred_width = pager_plugin_get_preferred_width;
152   widget_class->get_preferred_width_for_height  = pager_plugin_get_preferred_width_for_height;
153   widget_class->get_preferred_height = pager_plugin_get_preferred_height;
154   widget_class->get_preferred_height_for_width  = pager_plugin_get_preferred_height_for_width;
155 
156   plugin_class = XFCE_PANEL_PLUGIN_CLASS (klass);
157   plugin_class->construct = pager_plugin_construct;
158   plugin_class->free_data = pager_plugin_free_data;
159   plugin_class->size_changed = pager_plugin_size_changed;
160   plugin_class->mode_changed = pager_plugin_mode_changed;
161   plugin_class->configure_plugin = pager_plugin_configure_plugin;
162 
163   g_object_class_install_property (gobject_class,
164                                    PROP_WORKSPACE_SCROLLING,
165                                    g_param_spec_boolean ("workspace-scrolling",
166                                                          NULL, NULL,
167                                                          TRUE,
168                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
169 
170   g_object_class_install_property (gobject_class,
171                                    PROP_WRAP_WORKSPACES,
172                                    g_param_spec_boolean ("wrap-workspaces",
173                                                          NULL, NULL,
174                                                          FALSE,
175                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
176 
177   g_object_class_install_property (gobject_class,
178                                    PROP_MINIATURE_VIEW,
179                                    g_param_spec_boolean ("miniature-view",
180                                                          NULL, NULL,
181                                                          TRUE,
182                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
183 
184   g_object_class_install_property (gobject_class,
185                                    PROP_ROWS,
186                                    g_param_spec_uint ("rows",
187                                                       NULL, NULL,
188                                                       1, 50, 1,
189                                                       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
190 
191   g_object_class_install_property (gobject_class,
192                                    PROP_NUMBERING,
193                                    g_param_spec_boolean ("numbering",
194                                                          NULL, NULL,
195                                                          FALSE,
196                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
197 }
198 
199 
200 
201 static void
pager_plugin_init(PagerPlugin * plugin)202 pager_plugin_init (PagerPlugin *plugin)
203 {
204   plugin->wnck_screen = NULL;
205   plugin->scrolling = TRUE;
206   plugin->wrap_workspaces = FALSE;
207   plugin->miniature_view = TRUE;
208   plugin->rows = 1;
209   plugin->numbering = FALSE;
210   plugin->ratio = 1.0;
211   plugin->pager = NULL;
212 }
213 
214 
215 
216 static void
pager_plugin_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)217 pager_plugin_get_property (GObject    *object,
218                            guint       prop_id,
219                            GValue     *value,
220                            GParamSpec *pspec)
221 {
222   PagerPlugin *plugin = XFCE_PAGER_PLUGIN (object);
223 
224   switch (prop_id)
225     {
226     case PROP_WORKSPACE_SCROLLING:
227       g_value_set_boolean (value, plugin->scrolling);
228       break;
229 
230     case PROP_WRAP_WORKSPACES:
231       g_value_set_boolean (value, plugin->wrap_workspaces);
232       break;
233 
234     case PROP_MINIATURE_VIEW:
235       g_value_set_boolean (value, plugin->miniature_view);
236 
237       pager_plugin_screen_layout_changed (plugin);
238       break;
239 
240     case PROP_ROWS:
241       g_value_set_uint (value, plugin->rows);
242       break;
243 
244     case PROP_NUMBERING:
245       g_value_set_boolean (value, plugin->numbering);
246       break;
247 
248     default:
249       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
250       break;
251     }
252 }
253 
254 
255 
256 static void
pager_plugin_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)257 pager_plugin_set_property (GObject      *object,
258                            guint         prop_id,
259                            const GValue *value,
260                            GParamSpec   *pspec)
261 {
262   PagerPlugin *plugin = XFCE_PAGER_PLUGIN (object);
263 
264   switch (prop_id)
265     {
266     case PROP_WORKSPACE_SCROLLING:
267       plugin->scrolling = g_value_get_boolean (value);
268       break;
269 
270     case PROP_WRAP_WORKSPACES:
271       plugin->wrap_workspaces = g_value_get_boolean (value);
272       break;
273 
274     case PROP_MINIATURE_VIEW:
275       plugin->miniature_view = g_value_get_boolean (value);
276       break;
277 
278     case PROP_ROWS:
279       plugin->rows = g_value_get_uint (value);
280 
281       if (plugin->pager != NULL)
282         {
283           if (plugin->miniature_view)
284             {
285               if (!wnck_pager_set_n_rows (WNCK_PAGER (plugin->pager), plugin->rows))
286                 g_message ("Failed to set the number of pager rows. You probably "
287                            "have more than 1 pager in your panel setup.");
288             }
289           else
290             pager_buttons_set_n_rows (XFCE_PAGER_BUTTONS (plugin->pager), plugin->rows);
291         }
292       break;
293 
294     case PROP_NUMBERING:
295       plugin->numbering = g_value_get_boolean (value);
296 
297       if (plugin->pager != NULL
298           && !plugin->miniature_view)
299         pager_buttons_set_numbering (XFCE_PAGER_BUTTONS (plugin->pager), plugin->numbering);
300       break;
301 
302     default:
303       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
304       break;
305     }
306 }
307 
308 
309 
310 static void
pager_plugin_style_updated(GtkWidget * pager,gpointer user_data)311 pager_plugin_style_updated (GtkWidget *pager,
312                             gpointer   user_data)
313 {
314   GtkWidget               *toplevel = gtk_widget_get_toplevel (pager);
315   GtkStyleContext         *context;
316   GtkCssProvider          *provider;
317   GdkRGBA                 *bg_color;
318   gchar                   *css_string;
319   gchar                   *color_string;
320 
321   g_return_if_fail (gtk_widget_is_toplevel (toplevel));
322 
323   /* Get the background color of the panel to draw selected and hover states */
324   provider = gtk_css_provider_new ();
325   context = gtk_widget_get_style_context (GTK_WIDGET (toplevel));
326   gtk_style_context_get (context, GTK_STATE_FLAG_NORMAL,
327                          GTK_STYLE_PROPERTY_BACKGROUND_COLOR,
328                          &bg_color, NULL);
329   color_string = gdk_rgba_to_string(bg_color);
330   // FIXME: The shade value only works well visually for bright themes/panels
331   css_string = g_strdup_printf ("wnck-pager { background: %s; }"
332                                 "wnck-pager:selected { background: shade(%s, 0.7); }"
333                                 "wnck-pager:hover { background: shade(%s, 0.9); }",
334                                 color_string, color_string, color_string);
335   context = gtk_widget_get_style_context (pager);
336   gtk_css_provider_load_from_data (provider, css_string, -1, NULL);
337   gtk_style_context_add_provider (context,
338                                GTK_STYLE_PROVIDER (provider),
339                                GTK_STYLE_PROVIDER_PRIORITY_THEME);
340   gdk_rgba_free (bg_color);
341   g_free (color_string);
342   g_free (css_string);
343   g_object_unref (provider);
344 }
345 
346 
347 
348 static gboolean
pager_plugin_scroll_event(GtkWidget * widget,GdkEventScroll * event)349 pager_plugin_scroll_event (GtkWidget      *widget,
350                            GdkEventScroll *event)
351 {
352   PagerPlugin        *plugin = XFCE_PAGER_PLUGIN (widget);
353   WnckWorkspace      *active_ws;
354   WnckWorkspace      *new_ws;
355   gint                active_n;
356   gint                n_workspaces;
357   GdkScrollDirection  scrolling_direction;
358 
359   panel_return_val_if_fail (WNCK_IS_SCREEN (plugin->wnck_screen), FALSE);
360 
361   /* leave when scrolling is not enabled */
362   if (plugin->scrolling == FALSE)
363     return TRUE;
364 
365   if (event->direction != GDK_SCROLL_SMOOTH)
366     scrolling_direction = event->direction;
367   else if (event->delta_y < 0)
368     scrolling_direction = GDK_SCROLL_UP;
369   else if (event->delta_y > 0)
370     scrolling_direction = GDK_SCROLL_DOWN;
371   else if (event->delta_x < 0)
372     scrolling_direction = GDK_SCROLL_LEFT;
373   else if (event->delta_x > 0)
374     scrolling_direction = GDK_SCROLL_RIGHT;
375   else
376     {
377       panel_debug_filtered (PANEL_DEBUG_PAGER, "Scrolling event with no delta happened.");
378       return TRUE;
379     }
380 
381   active_ws = wnck_screen_get_active_workspace (plugin->wnck_screen);
382   active_n = wnck_workspace_get_number (active_ws);
383 
384   if (scrolling_direction == GDK_SCROLL_UP
385       || scrolling_direction == GDK_SCROLL_LEFT)
386     active_n--;
387   else
388     active_n++;
389 
390   n_workspaces = wnck_screen_get_workspace_count (plugin->wnck_screen) - 1;
391 
392   if (plugin->wrap_workspaces == TRUE)
393   {
394     /* wrap around */
395     if (active_n < 0)
396       active_n = n_workspaces;
397     else if (active_n > n_workspaces)
398       active_n = 0;
399   }
400   else if (active_n < 0 || active_n > n_workspaces )
401   {
402     /* we do not need to do anything */
403     return TRUE;
404   }
405 
406   new_ws = wnck_screen_get_workspace (plugin->wnck_screen, active_n);
407   if (new_ws != NULL && active_ws != new_ws)
408     wnck_workspace_activate (new_ws, event->time);
409 
410   return TRUE;
411 }
412 
413 
414 
415 static void
pager_plugin_drag_begin_event(GtkWidget * widget,GdkDragContext * context,gpointer user_data)416 pager_plugin_drag_begin_event (GtkWidget      *widget,
417                                GdkDragContext *context,
418                                gpointer        user_data)
419 {
420   PagerPlugin *plugin = user_data;
421 
422   panel_return_if_fail (XFCE_IS_PAGER_PLUGIN (plugin));
423   xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), TRUE);
424 }
425 
426 
427 
428 static void
pager_plugin_drag_end_event(GtkWidget * widget,GdkDragContext * context,gpointer user_data)429 pager_plugin_drag_end_event (GtkWidget      *widget,
430                              GdkDragContext *context,
431                              gpointer        user_data)
432 {
433   PagerPlugin *plugin = user_data;
434 
435   panel_return_if_fail (XFCE_IS_PAGER_PLUGIN (plugin));
436   xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), FALSE);
437 }
438 
439 
440 
441 static void
pager_plugin_screen_layout_changed(PagerPlugin * plugin)442 pager_plugin_screen_layout_changed (PagerPlugin *plugin)
443 {
444   XfcePanelPluginMode mode;
445   GtkOrientation      orientation;
446 
447   panel_return_if_fail (XFCE_IS_PAGER_PLUGIN (plugin));
448   panel_return_if_fail (WNCK_IS_SCREEN (plugin->wnck_screen));
449 
450   if (G_UNLIKELY (plugin->pager != NULL))
451     {
452       gtk_widget_destroy (GTK_WIDGET (plugin->pager));
453       wnck_screen_force_update (plugin->wnck_screen);
454     }
455 
456   mode = xfce_panel_plugin_get_mode (XFCE_PANEL_PLUGIN (plugin));
457   orientation =
458     (mode != XFCE_PANEL_PLUGIN_MODE_VERTICAL) ?
459     GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
460 
461   if (plugin->miniature_view)
462     {
463       plugin->pager = wnck_pager_new ();
464       wnck_pager_set_display_mode (WNCK_PAGER (plugin->pager), WNCK_PAGER_DISPLAY_CONTENT);
465       if (!wnck_pager_set_n_rows (WNCK_PAGER (plugin->pager), plugin->rows))
466         g_message ("Setting the pager rows returned false. Maybe the setting is not applied.");
467 
468       wnck_pager_set_orientation (WNCK_PAGER (plugin->pager), orientation);
469 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
470       plugin->ratio = (gfloat) gdk_screen_width () / (gfloat) gdk_screen_height ();
471 G_GNUC_END_IGNORE_DEPRECATIONS
472       g_signal_connect_after (G_OBJECT (plugin->pager), "drag-begin",
473                               G_CALLBACK (pager_plugin_drag_begin_event), plugin);
474       g_signal_connect_after (G_OBJECT (plugin->pager), "drag-end",
475                               G_CALLBACK (pager_plugin_drag_end_event), plugin);
476       g_signal_connect_swapped (G_OBJECT (plugin->pager), "scroll-event",
477                                 G_CALLBACK (pager_plugin_scroll_event), plugin);
478     }
479   else
480     {
481       plugin->pager = pager_buttons_new (plugin->wnck_screen);
482       pager_buttons_set_n_rows (XFCE_PAGER_BUTTONS (plugin->pager), plugin->rows);
483       pager_buttons_set_orientation (XFCE_PAGER_BUTTONS (plugin->pager), orientation);
484       pager_buttons_set_numbering (XFCE_PAGER_BUTTONS (plugin->pager), plugin->numbering);
485     }
486 
487   gtk_container_add (GTK_CONTAINER (plugin), plugin->pager);
488   gtk_widget_show (plugin->pager);
489 
490   /* Poke the style-updated signal to set the correct background color for the newly
491      created widget. Otherwise it may sometimes end up transparent. */
492   pager_plugin_style_updated (plugin->pager, NULL);
493 }
494 
495 
496 
497 static void
pager_plugin_screen_changed(GtkWidget * widget,GdkScreen * previous_screen)498 pager_plugin_screen_changed (GtkWidget *widget,
499                              GdkScreen *previous_screen)
500 {
501   PagerPlugin *plugin = XFCE_PAGER_PLUGIN (widget);
502   GdkScreen   *screen;
503   WnckScreen  *wnck_screen;
504 
505   screen = gtk_widget_get_screen (widget);
506 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
507   wnck_screen = wnck_screen_get (gdk_screen_get_number (screen));
508 G_GNUC_END_IGNORE_DEPRECATIONS
509 
510   if (plugin->wnck_screen != wnck_screen)
511     {
512       plugin->wnck_screen = wnck_screen;
513 
514       pager_plugin_screen_layout_changed (plugin);
515 
516       g_signal_connect_swapped (G_OBJECT (screen), "monitors-changed",
517          G_CALLBACK (pager_plugin_screen_layout_changed), plugin);
518       g_signal_connect_swapped (G_OBJECT (screen), "size-changed",
519          G_CALLBACK (pager_plugin_screen_layout_changed), plugin);
520     }
521 }
522 
523 
524 
525 static void
pager_plugin_construct(XfcePanelPlugin * panel_plugin)526 pager_plugin_construct (XfcePanelPlugin *panel_plugin)
527 {
528   PagerPlugin         *plugin = XFCE_PAGER_PLUGIN (panel_plugin);
529   GtkWidget           *mi, *image;
530   const PanelProperty  properties[] =
531   {
532     { "workspace-scrolling", G_TYPE_BOOLEAN },
533     { "wrap-workspaces", G_TYPE_BOOLEAN },
534     { "miniature-view", G_TYPE_BOOLEAN },
535     { "rows", G_TYPE_UINT },
536     { "numbering", G_TYPE_BOOLEAN },
537     { NULL }
538   };
539 
540   xfce_panel_plugin_menu_show_configure (panel_plugin);
541 
542 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
543   mi = gtk_image_menu_item_new_with_mnemonic (_("Workspace _Settings..."));
544 G_GNUC_END_IGNORE_DEPRECATIONS
545   xfce_panel_plugin_menu_insert_item (panel_plugin, GTK_MENU_ITEM (mi));
546   g_signal_connect (G_OBJECT (mi), "activate",
547       G_CALLBACK (pager_plugin_configure_workspace_settings), NULL);
548   gtk_widget_show (mi);
549 
550   image = gtk_image_new_from_icon_name ("org.xfce.panel.pager", GTK_ICON_SIZE_MENU);
551 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
552   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
553 G_GNUC_END_IGNORE_DEPRECATIONS
554   gtk_widget_show (image);
555 
556   panel_properties_bind (NULL, G_OBJECT (plugin),
557                          xfce_panel_plugin_get_property_base (panel_plugin),
558                          properties, FALSE);
559 
560   g_signal_connect (G_OBJECT (plugin), "screen-changed",
561       G_CALLBACK (pager_plugin_screen_changed), NULL);
562   pager_plugin_screen_changed (GTK_WIDGET (plugin), NULL);
563   g_signal_connect (G_OBJECT (plugin->pager), "style-updated",
564       G_CALLBACK (pager_plugin_style_updated), NULL);
565 }
566 
567 
568 
569 static void
pager_plugin_free_data(XfcePanelPlugin * panel_plugin)570 pager_plugin_free_data (XfcePanelPlugin *panel_plugin)
571 {
572   PagerPlugin *plugin = XFCE_PAGER_PLUGIN (panel_plugin);
573 
574   g_signal_handlers_disconnect_by_func (G_OBJECT (plugin),
575       pager_plugin_screen_changed, NULL);
576 }
577 
578 
579 
580 static gboolean
pager_plugin_size_changed(XfcePanelPlugin * panel_plugin,gint size)581 pager_plugin_size_changed (XfcePanelPlugin *panel_plugin,
582                            gint             size)
583 {
584   gtk_widget_queue_resize (GTK_WIDGET (panel_plugin));
585 
586   /* do not set fixed size */
587   return TRUE;
588 }
589 
590 
591 
592 static void
pager_plugin_mode_changed(XfcePanelPlugin * panel_plugin,XfcePanelPluginMode mode)593 pager_plugin_mode_changed (XfcePanelPlugin     *panel_plugin,
594                            XfcePanelPluginMode  mode)
595 {
596   PagerPlugin       *plugin = XFCE_PAGER_PLUGIN (panel_plugin);
597   GtkOrientation     orientation;
598 
599   orientation =
600     (mode != XFCE_PANEL_PLUGIN_MODE_VERTICAL) ?
601     GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
602 
603   if (plugin->miniature_view)
604     wnck_pager_set_orientation (WNCK_PAGER (plugin->pager), orientation);
605   else
606     pager_buttons_set_orientation (XFCE_PAGER_BUTTONS (plugin->pager), orientation);
607 }
608 
609 
610 
611 static void
pager_plugin_configure_workspace_settings(GtkWidget * button)612 pager_plugin_configure_workspace_settings (GtkWidget *button)
613 {
614   GdkScreen *screen;
615   GError    *error = NULL;
616   GtkWidget *toplevel;
617 
618   panel_return_if_fail (GTK_IS_WIDGET (button));
619 
620   screen = gtk_widget_get_screen (button);
621   if (G_UNLIKELY (screen == NULL))
622     screen = gdk_screen_get_default ();
623 
624   /* try to start the settings dialog */
625   if (!xfce_spawn_command_line (screen, WORKSPACE_SETTINGS_COMMAND,
626                                 FALSE, FALSE, TRUE, &error))
627     {
628       /* show an error dialog */
629       toplevel = gtk_widget_get_toplevel (button);
630       xfce_dialog_show_error (GTK_WINDOW (toplevel), error,
631           _("Unable to open the workspace settings"));
632       g_error_free (error);
633     }
634 }
635 
636 
637 
638 static void
pager_plugin_configure_n_workspaces_changed(WnckScreen * wnck_screen,WnckWorkspace * workspace,GtkBuilder * builder)639 pager_plugin_configure_n_workspaces_changed (WnckScreen    *wnck_screen,
640                                              WnckWorkspace *workspace,
641                                              GtkBuilder    *builder)
642 {
643   GObject       *object;
644   gdouble        upper, value;
645   WnckWorkspace *active_ws;
646 
647   panel_return_if_fail (WNCK_IS_SCREEN (wnck_screen));
648   panel_return_if_fail (GTK_IS_BUILDER (builder));
649 
650   object = gtk_builder_get_object (builder, "rows");
651 
652   upper = wnck_screen_get_workspace_count (wnck_screen);
653   if (upper == 1)
654     {
655       /* check if we ware in viewport mode */
656       active_ws = wnck_screen_get_active_workspace (wnck_screen);
657       if (wnck_workspace_is_virtual (active_ws))
658         {
659           /* number of rows * number of columns */
660           upper = (wnck_workspace_get_width (active_ws) / wnck_screen_get_width (wnck_screen))
661                   * (wnck_workspace_get_height (active_ws) / wnck_screen_get_height (wnck_screen));
662         }
663     }
664 
665   value = MIN (gtk_adjustment_get_value (GTK_ADJUSTMENT (object)), upper);
666 
667   g_object_set (G_OBJECT (object), "upper", upper, "value", value, NULL);
668 }
669 
670 
671 
672 static void
pager_plugin_configure_destroyed(gpointer data,GObject * where_the_object_was)673 pager_plugin_configure_destroyed (gpointer  data,
674                                   GObject  *where_the_object_was)
675 {
676   PagerPlugin *plugin = XFCE_PAGER_PLUGIN (data);
677 
678   g_signal_handlers_disconnect_by_func (G_OBJECT (plugin->wnck_screen),
679                                         pager_plugin_configure_n_workspaces_changed,
680                                         where_the_object_was);
681 }
682 
683 
684 
685 static void
pager_plugin_configure_plugin(XfcePanelPlugin * panel_plugin)686 pager_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
687 {
688   PagerPlugin *plugin = XFCE_PAGER_PLUGIN (panel_plugin);
689   GtkBuilder  *builder;
690   GObject     *dialog, *object;
691 
692   panel_return_if_fail (XFCE_IS_PAGER_PLUGIN (plugin));
693 
694   /* setup the dialog */
695   PANEL_UTILS_LINK_4UI
696   builder = panel_utils_builder_new (panel_plugin, pager_dialog_ui,
697                                      pager_dialog_ui_length, &dialog);
698   if (G_UNLIKELY (builder == NULL))
699     return;
700 
701   /* signals to monitor number of workspace changes */
702   g_signal_connect (G_OBJECT (plugin->wnck_screen), "workspace-created",
703       G_CALLBACK (pager_plugin_configure_n_workspaces_changed), builder);
704   g_signal_connect (G_OBJECT (plugin->wnck_screen), "workspace-destroyed",
705       G_CALLBACK (pager_plugin_configure_n_workspaces_changed), builder);
706   g_object_weak_ref (G_OBJECT (builder), pager_plugin_configure_destroyed, plugin);
707 
708   object = gtk_builder_get_object (builder, "settings-button");
709   panel_return_if_fail (GTK_IS_BUTTON (object));
710   g_signal_connect (G_OBJECT (object), "clicked",
711       G_CALLBACK (pager_plugin_configure_workspace_settings), dialog);
712 
713   object = gtk_builder_get_object (builder, "appearance");
714   panel_return_if_fail (GTK_IS_COMBO_BOX (object));
715   g_object_bind_property (G_OBJECT (plugin), "miniature-view",
716                           G_OBJECT (object), "active",
717                           G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
718 
719   object = gtk_builder_get_object (builder, "rows");
720   panel_return_if_fail (GTK_IS_ADJUSTMENT (object));
721   g_object_bind_property (G_OBJECT (plugin), "rows",
722                           G_OBJECT (object), "value",
723                           G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
724 
725   plugin->scrolling_label = gtk_builder_get_object (builder, "workspace-scrolling-label");
726   g_object_bind_property (G_OBJECT (plugin), "miniature-view",
727                           G_OBJECT (plugin->scrolling_label), "visible",
728                           G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN);
729   plugin->scrolling_switch = gtk_builder_get_object (builder, "workspace-scrolling");
730   panel_return_if_fail (GTK_IS_SWITCH (plugin->scrolling_switch));
731   g_object_bind_property (G_OBJECT (plugin), "miniature-view",
732                           G_OBJECT (plugin->scrolling_switch), "visible",
733                           G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN);
734   g_object_bind_property (G_OBJECT (plugin), "workspace-scrolling",
735                           G_OBJECT (plugin->scrolling_switch), "active",
736                           G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
737 
738   plugin->numbering_label = gtk_builder_get_object (builder, "numbering-label");
739   g_object_bind_property (G_OBJECT (plugin), "miniature-view",
740                           G_OBJECT (plugin->numbering_label), "visible",
741                           G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN);
742   plugin->numbering_switch = gtk_builder_get_object (builder, "numbering");
743   panel_return_if_fail (GTK_IS_SWITCH (plugin->numbering_switch));
744   g_object_bind_property (G_OBJECT (plugin), "miniature-view",
745                           G_OBJECT (plugin->numbering_switch), "visible",
746                           G_BINDING_SYNC_CREATE | G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN);
747   g_object_bind_property (G_OBJECT (plugin), "numbering",
748                           G_OBJECT (plugin->numbering_switch), "active",
749                           G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
750 
751   /* update the rows limit */
752   pager_plugin_configure_n_workspaces_changed (plugin->wnck_screen, NULL, builder);
753 
754   gtk_widget_show (GTK_WIDGET (dialog));
755 }
756 
757 
758 static void
pager_plugin_get_preferred_width(GtkWidget * widget,gint * minimum_width,gint * natural_width)759 pager_plugin_get_preferred_width (GtkWidget *widget,
760                                   gint      *minimum_width,
761                                   gint      *natural_width)
762 {
763   PagerPlugin         *plugin = XFCE_PAGER_PLUGIN (widget);
764   XfcePanelPluginMode  mode;
765   gint                 n_workspaces, n_cols;
766   gint                 min_width = 0;
767   gint                 nat_width = 0;
768 
769   if (plugin->pager != NULL)
770     gtk_widget_get_preferred_width (plugin->pager, &min_width, &nat_width);
771 
772   mode = xfce_panel_plugin_get_mode (XFCE_PANEL_PLUGIN (plugin));
773   if (mode == XFCE_PANEL_PLUGIN_MODE_VERTICAL ||
774       mode == XFCE_PANEL_PLUGIN_MODE_DESKBAR)
775     min_width = nat_width = xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin));
776   else if (plugin->miniature_view)
777     {
778       n_workspaces = wnck_screen_get_workspace_count (plugin->wnck_screen);
779       n_cols = MAX (1, (n_workspaces + plugin->rows - 1) / plugin->rows);
780       min_width = nat_width = (gint) (xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin)) / plugin->rows * plugin->ratio * n_cols);
781     }
782 
783   if (minimum_width != NULL)
784     *minimum_width = min_width;
785 
786   if (natural_width != NULL)
787     *natural_width = nat_width;
788 }
789 
790 static void
pager_plugin_get_preferred_height(GtkWidget * widget,gint * minimum_height,gint * natural_height)791 pager_plugin_get_preferred_height (GtkWidget *widget,
792                                    gint      *minimum_height,
793                                    gint      *natural_height)
794 {
795   PagerPlugin         *plugin = XFCE_PAGER_PLUGIN (widget);
796   XfcePanelPluginMode  mode;
797   gint                 n_workspaces, n_cols;
798   gint                 min_height = 0;
799   gint                 nat_height = 0;
800 
801   if (plugin->pager != NULL)
802     gtk_widget_get_preferred_height (plugin->pager, &min_height, &nat_height);
803 
804   mode = xfce_panel_plugin_get_mode (XFCE_PANEL_PLUGIN (plugin));
805   if (mode == XFCE_PANEL_PLUGIN_MODE_HORIZONTAL)
806     min_height = nat_height = xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin));
807   else if (plugin->miniature_view)
808     {
809       n_workspaces = wnck_screen_get_workspace_count (plugin->wnck_screen);
810       n_cols = MAX (1, (n_workspaces + plugin->rows - 1) / plugin->rows);
811       if (mode == XFCE_PANEL_PLUGIN_MODE_VERTICAL)
812         min_height = nat_height = (gint) (xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin)) / plugin->rows / plugin->ratio * n_cols);
813       else /* (mode == XFCE_PANEL_PLUGIN_MODE_DESKBAR) */
814         min_height = nat_height = (gint) (xfce_panel_plugin_get_size (XFCE_PANEL_PLUGIN (plugin)) / n_cols / plugin->ratio * plugin->rows);
815     }
816 
817   if (minimum_height != NULL)
818     *minimum_height = min_height;
819 
820   if (natural_height != NULL)
821     *natural_height = nat_height;
822 }
823 
824 static void
pager_plugin_get_preferred_width_for_height(GtkWidget * widget,gint height,gint * minimum_width,gint * natural_width)825 pager_plugin_get_preferred_width_for_height (GtkWidget *widget,
826                                              gint       height,
827                                              gint      *minimum_width,
828                                              gint      *natural_width)
829 {
830   pager_plugin_get_preferred_width (widget, minimum_width, natural_width);
831 }
832 
833 static void
pager_plugin_get_preferred_height_for_width(GtkWidget * widget,gint width,gint * minimum_height,gint * natural_height)834 pager_plugin_get_preferred_height_for_width (GtkWidget *widget,
835                                              gint       width,
836                                              gint      *minimum_height,
837                                              gint      *natural_height)
838 {
839   pager_plugin_get_preferred_height (widget, minimum_height, natural_height);
840 }
841