/*
* Copyright (C) 2008 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by Neil Jagdish Patel
*
*/
#if HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#define WNCK_I_KNOW_THIS_IS_UNSTABLE
#include
#include
#include
#include
#include
#if GTK_CHECK_VERSION (3, 0, 0)
#define gtk_rc_style_unref g_object_ref
#endif
#include "task-list.h"
#include "task-title.h"
#define APPLET_SCHEMA "org.mate.panel.applet.mate-window-picker-applet"
#define SHOW_WIN_KEY "show-all-windows"
typedef struct
{
GtkWidget *tasks;
GtkWidget *applet;
GtkWidget *title;
GSettings *settings;
} WinPickerApp;
static WinPickerApp *mainapp;
static gpointer parent_class;
static void cw_panel_background_changed (MatePanelApplet *applet,
MatePanelAppletBackgroundType type,
GdkColor *colour,
#if GTK_CHECK_VERSION (3, 0, 0)
cairo_pattern_t *pattern,
#else
GdkPixmap *pixmap,
#endif
gpointer user_data);
static void display_about_dialog (GtkAction *action,
WinPickerApp *applet);
static void display_prefs_dialog (GtkAction *action,
WinPickerApp *applet);
static const GtkActionEntry window_picker_menu_actions [] = {
{ "MenuPrefs", GTK_STOCK_PREFERENCES, N_("_Preferences"),
NULL, NULL,
G_CALLBACK (display_prefs_dialog) },
{ "MenuAbout", GTK_STOCK_ABOUT, N_("_About"),
NULL, NULL,
G_CALLBACK (display_about_dialog) }
};
static const gchar *close_window_authors [] = {
"Neil J. Patel ",
"Stefano Karapetsas ",
NULL
};
static void
on_show_all_windows_changed (GSettings *settings,
gchar *key,
gpointer data)
{
WinPickerApp *app;
gboolean show_windows = TRUE;
app = (WinPickerApp*)data;
show_windows = g_settings_get_boolean (settings, SHOW_WIN_KEY);
g_object_set (app->tasks, "show_all_windows", show_windows, NULL);
}
static inline void
force_no_focus_padding (GtkWidget *widget)
{
static gboolean first_time = TRUE;
if (first_time)
{
gtk_rc_parse_string ("\n"
" style \"na-tray-style\"\n"
" {\n"
" GtkWidget::focus-line-width=0\n"
" GtkWidget::focus-padding=0\n"
" }\n"
"\n"
" widget \"*.na-tray\" style \"na-tray-style\"\n"
"\n");
first_time = FALSE;
}
gtk_widget_set_name (widget, "na-tray");
}
static void
cw_applet_finalize (GObject *object)
{
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
static gboolean
cw_applet_fill (MatePanelApplet *applet,
const gchar *iid,
gpointer data)
{
WnckScreen *screen;
WinPickerApp *app;
GtkWidget *eb, *tasks, *title;
gchar *ui_path;
GtkActionGroup *action_group;
GObjectClass *object_class;
if (strcmp (iid, "MateWindowPicker") != 0)
return FALSE;
bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
wnck_set_client_type (WNCK_CLIENT_TYPE_PAGER);
app = g_slice_new0 (WinPickerApp);
mainapp = app;
screen = wnck_screen_get_default ();
object_class = G_OBJECT_GET_CLASS (G_OBJECT(applet));
object_class->finalize = cw_applet_finalize;
parent_class = g_type_class_peek_parent (object_class);
/* gsettings prefs */
app->settings = mate_panel_applet_settings_new (applet, APPLET_SCHEMA);
g_signal_connect (app->settings, "changed::" SHOW_WIN_KEY,
G_CALLBACK (on_show_all_windows_changed), app);
app->applet = GTK_WIDGET (applet);
force_no_focus_padding (GTK_WIDGET (applet));
gtk_container_set_border_width (GTK_CONTAINER (applet), 0);
eb = gtk_hbox_new (FALSE, 6);
gtk_container_add (GTK_CONTAINER (applet), eb);
gtk_container_set_border_width (GTK_CONTAINER (eb), 0);
tasks = app->tasks = task_list_get_default ();
gtk_box_pack_start (GTK_BOX (eb), tasks, FALSE, FALSE, 0);
title = app->title = task_title_new ();
gtk_box_pack_start (GTK_BOX (eb), title, TRUE, TRUE, 0);
gtk_widget_show_all (GTK_WIDGET (applet));
on_show_all_windows_changed (app->settings, SHOW_WIN_KEY, app);
/* Signals */
g_signal_connect (applet, "change-background",
G_CALLBACK (cw_panel_background_changed), NULL);
action_group = gtk_action_group_new ("MateWindowPicker Applet Actions");
gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
gtk_action_group_add_actions (action_group,
window_picker_menu_actions,
G_N_ELEMENTS (window_picker_menu_actions),
app);
ui_path = g_build_filename (MATEWINDOWPICKER_MENU_UI_DIR, "mate-window-picker-applet-menu.xml", NULL);
mate_panel_applet_setup_menu_from_file (MATE_PANEL_APPLET (app->applet),
ui_path, action_group);
g_free (ui_path);
g_object_unref (action_group);
mate_panel_applet_set_flags (MATE_PANEL_APPLET (applet),
MATE_PANEL_APPLET_EXPAND_MAJOR
| MATE_PANEL_APPLET_EXPAND_MINOR
| MATE_PANEL_APPLET_HAS_HANDLE);
return TRUE;
}
MATE_PANEL_APPLET_OUT_PROCESS_FACTORY ("MateWindowPickerFactory",
PANEL_TYPE_APPLET,
"MateWindowPicker",
cw_applet_fill,
NULL);
static void
cw_panel_background_changed (MatePanelApplet *applet,
MatePanelAppletBackgroundType type,
GdkColor *colour,
#if GTK_CHECK_VERSION (3, 0, 0)
cairo_pattern_t *pattern,
#else
GdkPixmap *pixmap,
#endif
gpointer user_data)
{
GtkRcStyle *rc_style;
GtkStyle *style;
/* reset style */
gtk_widget_set_style (GTK_WIDGET (applet), NULL);
rc_style = gtk_rc_style_new ();
gtk_widget_modify_style (GTK_WIDGET (applet), rc_style);
gtk_rc_style_unref (rc_style);
gtk_widget_set_style (mainapp->title, NULL);
rc_style = gtk_rc_style_new ();
gtk_widget_modify_style (mainapp->title, rc_style);
gtk_rc_style_unref (rc_style);
switch (type)
{
case PANEL_NO_BACKGROUND:
break;
case PANEL_COLOR_BACKGROUND:
gtk_widget_modify_bg (GTK_WIDGET (applet), GTK_STATE_NORMAL, colour);
gtk_widget_modify_bg (mainapp->title, GTK_STATE_NORMAL, colour);
break;
case PANEL_PIXMAP_BACKGROUND:
#if GTK_CHECK_VERSION (3, 0, 0)
/* FIXME */
#else
style = gtk_style_copy (GTK_WIDGET (applet)->style);
if (style->bg_pixmap[GTK_STATE_NORMAL])
g_object_unref (style->bg_pixmap[GTK_STATE_NORMAL]);
style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (pixmap);
gtk_widget_set_style (GTK_WIDGET (applet), style);
g_object_unref (style);
#endif
/*style = gtk_style_copy (mainapp->title->style);
if (style->bg_pixmap[GTK_STATE_NORMAL])
g_object_unref (style->bg_pixmap[GTK_STATE_NORMAL]);
style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (pixmap);
gtk_widget_set_style (mainapp->title, style);
g_object_unref (style);*/
break;
}
}
static void
display_about_dialog (GtkAction *action,
WinPickerApp *applet)
{
GtkWidget *panel_about_dialog;
panel_about_dialog = mate_about_dialog_new ();
g_object_set (panel_about_dialog,
"name", _("Window Picker"),
"comments", _("Window Picker"),
"version", PACKAGE_VERSION,
"authors", close_window_authors,
"logo-icon-name", "preferences-system-windows",
"copyright", "Copyright \xc2\xa9 2008 Canonical Ltd\n"
"Copyright \xc2\xa9 2013-2014 Stefano Karapetsas",
NULL);
gtk_widget_show (panel_about_dialog);
g_signal_connect (panel_about_dialog, "response",
G_CALLBACK (gtk_widget_destroy), NULL);
gtk_window_present (GTK_WINDOW (panel_about_dialog));
}
static void
on_checkbox_toggled (GtkToggleButton *check, gpointer null)
{
gboolean is_active;
is_active = gtk_toggle_button_get_active (check);
g_settings_set_boolean (mainapp->settings, SHOW_WIN_KEY, is_active);
}
static void
display_prefs_dialog (GtkAction *action,
WinPickerApp *applet)
{
GtkWidget *window, *box, *vbox, *nb, *hbox, *label, *check, *button;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), _("Preferences"));
gtk_window_set_type_hint (GTK_WINDOW (window),
GDK_WINDOW_TYPE_HINT_DIALOG);
gtk_container_set_border_width (GTK_CONTAINER (window), 12);
box = gtk_vbox_new (FALSE, 8);
gtk_container_add (GTK_CONTAINER (window), box);
nb = gtk_notebook_new ();
g_object_set (nb, "show-tabs", FALSE, "show-border", TRUE, NULL);
gtk_box_pack_start (GTK_BOX (box), nb, TRUE, TRUE, 0);
vbox = gtk_vbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
gtk_notebook_append_page (GTK_NOTEBOOK (nb), vbox, NULL);
check = gtk_check_button_new_with_label (_("Show windows from all workspaces"));
gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, TRUE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
g_settings_get_boolean (mainapp->settings, SHOW_WIN_KEY));
g_signal_connect (check, "toggled",
G_CALLBACK (on_checkbox_toggled), NULL);
check = gtk_label_new (" ");
gtk_box_pack_start (GTK_BOX (vbox), check, TRUE, TRUE, 0);
gtk_widget_set_size_request (nb, -1, 100);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), hbox, TRUE, TRUE, 0);
label = gtk_label_new (" ");
gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show_all (window);
g_signal_connect (window, "delete-event",
G_CALLBACK (gtk_widget_destroy), window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroy), window);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_widget_destroy), window);
gtk_window_present (GTK_WINDOW (window));
}