Releasing debian version 0.10.0-2.
[debian/lxpanel.git] / plugins / pager.c
1 /* pager.c -- pager module of lxpanel project
2 *
3 * Copyright (C) 2009 Dongxu Li <song6song@sourceforge.net>
4 * 2012 Julien Lavergne <gilir@ubuntu.com>
5 * 2014 Andriy Grytsenko <andrej@rep.kiev.ua>
6 * 2018 number Zero <numzero@users.sf.net>
7 *
8 * This file is part of lxpanel.
9 *
10 * lxpanel is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * lxpanel is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with sawfish; see the file COPYING. If not, write to
22 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301 USA.
24 */
25
26 #include <gtk/gtk.h>
27 #include <gdk/gdkx.h>
28 #include <libfm/fm-gtk.h>
29
30 #include <glib/gi18n.h>
31 #ifndef WNCK_I_KNOW_THIS_IS_UNSTABLE
32 #define WNCK_I_KNOW_THIS_IS_UNSTABLE
33 #endif
34 #include <libwnck/libwnck.h>
35
36 #include "misc.h"
37 #include "plugin.h"
38
39 typedef struct
40 {
41 WnckPager *pager;
42 gint border;
43 } PagerData;
44
45 /* command to configure desktop, it will be set by .config callback */
46 static const char *configure_command = NULL;
47
48 static void on_realize(GtkWidget *p, LXPanel *panel)
49 {
50 PagerData *d = lxpanel_plugin_get_data(p);
51 int rows, r, h = panel_get_height(panel) - 2 * d->border;
52
53 /* set geometry */
54 wnck_pager_set_orientation(d->pager, panel_get_orientation(panel));
55 if (panel_get_orientation(panel) == GTK_ORIENTATION_VERTICAL)
56 h *= ((gfloat) gdk_screen_height() / (gfloat) gdk_screen_width());
57 rows = h / (panel_get_icon_size(panel) * 2) + 1; /* min */
58 r = (h - 2) / panel_get_icon_size(panel); /* max */
59 /* g_debug("pager for height %d and icon size %d: %d to %d",panel_get_height(panel),panel_get_icon_size(panel),r,rows); */
60 rows = MAX(rows, r);
61 wnck_pager_set_n_rows(d->pager, rows);
62 }
63
64 static void on_size_allocate(GtkWidget *p, GdkRectangle *allocation, LXPanel *panel)
65 {
66 /* g_debug("pager: on_size_allocate(): %dx%d", allocation->width, allocation->height); */
67 on_realize(p, panel);
68 }
69
70 static gboolean on_scroll_event(GtkWidget * p, GdkEventScroll * ev, LXPanel *panel)
71 {
72 int desknum = get_net_current_desktop();
73 int desks = get_net_number_of_desktops();
74 Screen *xscreen = GDK_SCREEN_XSCREEN(gtk_widget_get_screen(p));
75
76 switch (ev->direction) {
77 case GDK_SCROLL_DOWN:
78 desknum++;
79 break;
80 case GDK_SCROLL_UP:
81 desknum--;
82 break;
83 default:
84 return FALSE;
85 }
86
87 if (desknum < 0 || desknum >= desks)
88 return TRUE;
89
90 Xclimsgx(xscreen, RootWindowOfScreen(xscreen), a_NET_CURRENT_DESKTOP, desknum, 0, 0, 0, 0);
91 return TRUE;
92 }
93
94 static GtkWidget *pager_constructor(LXPanel *panel, config_setting_t *settings)
95 {
96 GtkWidget *p, *w;
97 PagerData *d;
98 int border = 1; /* NOTE: old 'pager' used 2, WnckPager has 1, need 1 more */
99
100 /* FIXME: use some global setting for border */
101 #if GTK_CHECK_VERSION(3, 0, 0)
102 w = wnck_pager_new();
103 #else
104 w = wnck_pager_new(NULL);
105 #endif
106 g_return_val_if_fail(w != NULL, NULL);
107 d = g_new(PagerData, 1);
108 d->pager = WNCK_PAGER(w);
109 d->border = border;
110 p = gtk_event_box_new();
111 gtk_widget_set_has_window(p, FALSE);
112 lxpanel_plugin_set_data(p, d, g_free);
113
114 /* we cannot configure pager until it added into widgets hierarchy */
115 g_signal_connect(p, "realize", G_CALLBACK(on_realize), panel);
116 g_signal_connect(p, "size-allocate", G_CALLBACK(on_size_allocate), panel);
117 g_signal_connect(p, "scroll-event", G_CALLBACK(on_scroll_event), panel);
118 wnck_pager_set_display_mode(d->pager, WNCK_PAGER_DISPLAY_CONTENT);
119
120 gtk_widget_show(w);
121
122 /* add an additional container to setup a border */
123 w = gtk_event_box_new();
124 gtk_widget_set_has_window(w, FALSE);
125 gtk_container_set_border_width(GTK_CONTAINER(w), border);
126 gtk_container_add(GTK_CONTAINER(w), (GtkWidget*)d->pager);
127 gtk_widget_show(w);
128 gtk_container_add(GTK_CONTAINER(p), w);
129
130 return p;
131 }
132
133 /* this is a modified version of patch from Lubuntu */
134 static GtkWidget *pager_configure(LXPanel *panel, GtkWidget *instance)
135 {
136 if (configure_command)
137 fm_launch_command_simple(NULL, NULL, G_APP_INFO_CREATE_NONE,
138 configure_command, NULL);
139 else
140 fm_show_error(NULL, NULL,
141 _("Sorry, there was no window manager configuration program found."));
142 return NULL; /* no configuration dialog of lxpanel available */
143 }
144
145 static void pager_menu_callback(GtkWidget *widget, gpointer data)
146 {
147 gtk_widget_set_sensitive(widget, FALSE);
148 }
149
150 static gboolean pager_update_context_menu(GtkWidget *plugin, GtkMenu *menu)
151 {
152 GdkScreen *screen = gtk_widget_get_screen(plugin);
153 const char *wm_name = gdk_x11_screen_get_window_manager_name(screen);
154 char *path = NULL;
155
156 /* update configure_command */
157 configure_command = NULL;
158 if (g_strcmp0(wm_name, "Openbox") == 0)
159 {
160 if ((path = g_find_program_in_path("obconf")))
161 {
162 configure_command = "obconf --tab 6";
163 }
164 }
165 else if (g_strcmp0(wm_name, "compiz") == 0)
166 {
167 if ((path = g_find_program_in_path("ccsm")))
168 {
169 configure_command = "ccsm";
170 }
171 else if ((path = g_find_program_in_path("simple-ccsm")))
172 {
173 configure_command = "simple-ccsm";
174 }
175 }
176 /* FIXME: support other WMs */
177 if (configure_command == NULL)
178 {
179 /* disable 'Settings' menu item */
180 gtk_container_foreach(GTK_CONTAINER(menu), pager_menu_callback, NULL);
181 }
182 /* FIXME: else replace 'Settings' item label with "Launch Workspaces Configurator (%s)" */
183 g_free(path);
184 return FALSE;
185 }
186
187 static void pager_panel_configuration_changed(LXPanel *panel, GtkWidget *p)
188 {
189 on_realize(p, panel);
190 }
191
192 static LXPanelPluginInit wnck_pager = {
193 .name = N_("Desktop Pager"),
194 .description = N_("Simple pager plugin"),
195
196 .superseded = TRUE,
197 .new_instance = pager_constructor,
198 .config = pager_configure,
199 .update_context_menu = pager_update_context_menu,
200 .reconfigure = pager_panel_configuration_changed
201 };
202
203 static void pager_wnck_init(void)
204 {
205 lxpanel_register_plugin_type("wnckpager", &wnck_pager);
206 }
207
208 LXPanelPluginInit lxpanel_static_plugin_pager = {
209 .name = N_("Desktop Pager"),
210 .description = N_("Simple pager plugin"),
211
212 .init = pager_wnck_init,
213 .new_instance = pager_constructor,
214 .config = pager_configure,
215 .update_context_menu = pager_update_context_menu,
216 .reconfigure = pager_panel_configuration_changed
217 };