summaryrefslogtreecommitdiffstats
path: root/src/virt-viewer-app.c
diff options
context:
space:
mode:
authorEduardo Lima (Etrunko) <etrunko@redhat.com>2015-12-09 18:11:37 -0200
committerFabiano FidĂȘncio <fidencio@redhat.com>2016-02-18 21:45:56 +0100
commita9ce19f84864cc402ea1b4682a94fe53895bb13f (patch)
tree167a3de3998be59443ec506944d06f9eb675d4d2 /src/virt-viewer-app.c
parent7a54b96dbebfeb44f73a3e48e11f32006763a3b6 (diff)
downloadvirt-viewer-a9ce19f84864cc402ea1b4682a94fe53895bb13f.tar.gz
virt-viewer-a9ce19f84864cc402ea1b4682a94fe53895bb13f.tar.xz
virt-viewer-a9ce19f84864cc402ea1b4682a94fe53895bb13f.zip
Port to GtkApplication API's
Most of this patch consists in code being shuffled around to fit the expected flow while using the new APIs. I tried my best to make this patch the less intrusive as possible. Main changes are: - Updated build requirements * glib version 2.38 * gtk+ version 3.10 * gio - VirtViewerApp is now a subclass of GtkApplication. Some mainloop calls were replaced: * gtk_main() -> g_application_run() * gtk_quit() -> g_application_quit() - Unified command line option handling. The logic has moved from the main functions and split in common options, and specific ones for each application. With this, the main functions were highly simplified, and now basically responsible for instantiating the App object and running the main loop. - All Window objects must be associated with the Application. With this, there is no need to emit our own 'window-added'/'window- removed' signals, as those will be emited by GtkApplication whenever gtk_application_add_window() and gtk_application_remove_window() are called. Also, 'window-removed' was not being used anywhere. Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
Diffstat (limited to 'src/virt-viewer-app.c')
-rw-r--r--src/virt-viewer-app.c158
1 files changed, 102 insertions, 56 deletions
diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index 7f7fed3..aa5e905 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <unistd.h>
#include <locale.h>
+#include <gio/gio.h>
#include <glib/gprintf.h>
#include <glib/gi18n.h>
@@ -102,6 +103,7 @@ static void virt_viewer_app_update_pretty_address(VirtViewerApp *self);
static void virt_viewer_app_set_fullscreen(VirtViewerApp *self, gboolean fullscreen);
static void virt_viewer_app_update_menu_displays(VirtViewerApp *self);
static void virt_viewer_update_smartcard_accels(VirtViewerApp *self);
+static void virt_viewer_app_add_option_entries(VirtViewerApp *self, GOptionContext *context, GOptionGroup *group);
struct _VirtViewerAppPrivate {
@@ -154,7 +156,7 @@ struct _VirtViewerAppPrivate {
};
-G_DEFINE_ABSTRACT_TYPE(VirtViewerApp, virt_viewer_app, G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE(VirtViewerApp, virt_viewer_app, GTK_TYPE_APPLICATION)
#define GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE_APP, VirtViewerAppPrivate))
@@ -173,14 +175,6 @@ enum {
PROP_UUID,
};
-enum {
- SIGNAL_WINDOW_ADDED,
- SIGNAL_WINDOW_REMOVED,
- SIGNAL_LAST,
-};
-
-static guint signals[SIGNAL_LAST];
-
void
virt_viewer_app_set_debug(gboolean debug)
{
@@ -297,7 +291,7 @@ virt_viewer_app_quit(VirtViewerApp *self)
}
}
- gtk_main_quit();
+ g_application_quit(G_APPLICATION(self));
}
static gint
@@ -948,12 +942,13 @@ virt_viewer_app_window_new(VirtViewerApp *self, gint nth)
virt_viewer_app_update_menu_displays(self);
virt_viewer_window_set_usb_options_sensitive(window, virt_viewer_app_has_usbredir(self));
- g_signal_emit(self, signals[SIGNAL_WINDOW_ADDED], 0, window);
+ w = virt_viewer_window_get_window(window);
+ g_object_set_data(G_OBJECT(w), "virt-viewer-window", window);
+ gtk_application_add_window(GTK_APPLICATION(self), w);
if (self->priv->fullscreen)
app_window_try_fullscreen(self, window, nth);
- w = virt_viewer_window_get_window(window);
g_signal_connect(w, "hide", G_CALLBACK(viewer_window_visible_cb), self);
g_signal_connect(w, "show", G_CALLBACK(viewer_window_visible_cb), self);
g_signal_connect(w, "focus-in-event", G_CALLBACK(viewer_window_focus_in_cb), self);
@@ -1068,8 +1063,6 @@ static void virt_viewer_app_remove_nth_window(VirtViewerApp *self,
g_debug("Remove window %d %p", nth, win);
self->priv->windows = g_list_remove(self->priv->windows, win);
- g_signal_emit(self, signals[SIGNAL_WINDOW_REMOVED], 0, win);
-
g_object_unref(win);
}
@@ -1423,7 +1416,7 @@ virt_viewer_app_default_deactivated(VirtViewerApp *self, gboolean connect_error)
}
if (self->priv->quit_on_disconnect)
- gtk_main_quit();
+ g_application_quit(G_APPLICATION(self));
}
static void
@@ -1501,7 +1494,7 @@ virt_viewer_app_disconnected(VirtViewerSession *session G_GNUC_UNUSED, const gch
virt_viewer_app_hide_all_windows(self);
if (priv->quitting)
- gtk_main_quit();
+ g_application_quit(G_APPLICATION(self));
if (connect_error) {
GtkWidget *dialog = virt_viewer_app_make_message_dialog(self,
@@ -1768,6 +1761,7 @@ gboolean virt_viewer_app_start(VirtViewerApp *self, GError **error)
static int opt_zoom = NORMAL_ZOOM_LEVEL;
static gchar *opt_hotkeys = NULL;
+static gboolean opt_version = FALSE;
static gboolean opt_verbose = FALSE;
static gboolean opt_debug = FALSE;
static gboolean opt_fullscreen = FALSE;
@@ -1787,8 +1781,6 @@ virt_viewer_app_init(VirtViewerApp *self)
self->priv = GET_PRIVATE(self);
gtk_window_set_default_icon_name("virt-viewer");
- virt_viewer_app_set_debug(opt_debug);
- virt_viewer_app_set_fullscreen(self, opt_fullscreen);
self->priv->displays = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
self->priv->config = g_key_file_new();
@@ -1804,14 +1796,7 @@ virt_viewer_app_init(VirtViewerApp *self)
g_clear_error(&error);
- if (opt_zoom < MIN_ZOOM_LEVEL || opt_zoom > MAX_ZOOM_LEVEL) {
- g_printerr(_("Zoom level must be within %d-%d\n"), MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL);
- opt_zoom = NORMAL_ZOOM_LEVEL;
- }
-
self->priv->initial_display_map = virt_viewer_app_get_monitor_mapping_for_section(self, "fallback");
- self->priv->verbose = opt_verbose;
- self->priv->quit_on_disconnect = opt_kiosk ? opt_kiosk_quit : TRUE;
g_signal_connect(self, "notify::guest-name", G_CALLBACK(title_maybe_changed), NULL);
g_signal_connect(self, "notify::title", G_CALLBACK(title_maybe_changed), NULL);
g_signal_connect(self, "notify::guri", G_CALLBACK(title_maybe_changed), NULL);
@@ -1870,9 +1855,18 @@ virt_viewer_update_smartcard_accels(VirtViewerApp *self)
}
static void
-virt_viewer_app_constructed(GObject *object)
+virt_viewer_app_on_application_startup(GApplication *app)
{
- VirtViewerApp *self = VIRT_VIEWER_APP(object);
+ VirtViewerApp *self = VIRT_VIEWER_APP(app);
+ GError *error = NULL;
+
+ G_APPLICATION_CLASS(virt_viewer_app_parent_class)->startup(app);
+
+ virt_viewer_app_set_debug(opt_debug);
+ virt_viewer_app_set_fullscreen(self, opt_fullscreen);
+
+ self->priv->verbose = opt_verbose;
+ self->priv->quit_on_disconnect = opt_kiosk ? opt_kiosk_quit : TRUE;
self->priv->main_window = virt_viewer_app_window_new(self,
virt_viewer_app_get_first_monitor(self));
@@ -1880,6 +1874,12 @@ virt_viewer_app_constructed(GObject *object)
virt_viewer_app_set_kiosk(self, opt_kiosk);
virt_viewer_app_set_hotkeys(self, opt_hotkeys);
+
+ if (opt_zoom < MIN_ZOOM_LEVEL || opt_zoom > MAX_ZOOM_LEVEL) {
+ g_printerr(_("Zoom level must be within %d-%d\n"), MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL);
+ opt_zoom = NORMAL_ZOOM_LEVEL;
+ }
+
virt_viewer_window_set_zoom_level(self->priv->main_window, opt_zoom);
virt_viewer_set_insert_smartcard_accel(self, GDK_KEY_F8, GDK_SHIFT_MASK);
@@ -1890,25 +1890,92 @@ virt_viewer_app_constructed(GObject *object)
gtk_accel_map_add_entry("<virt-viewer>/view/zoom-out", GDK_KEY_minus, GDK_CONTROL_MASK);
gtk_accel_map_add_entry("<virt-viewer>/view/zoom-in", GDK_KEY_plus, GDK_CONTROL_MASK);
gtk_accel_map_add_entry("<virt-viewer>/send/secure-attention", GDK_KEY_End, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+
+ if (!virt_viewer_app_start(self, &error)) {
+ if (error && !g_error_matches(error, VIRT_VIEWER_ERROR, VIRT_VIEWER_ERROR_CANCELLED))
+ virt_viewer_app_simple_message_dialog(self, error->message);
+
+ g_clear_error(&error);
+ g_application_quit(app);
+ return;
+ }
+
+ g_application_hold(app);
+}
+
+static gboolean
+virt_viewer_app_local_command_line (GApplication *gapp,
+ gchar ***args,
+ int *status)
+{
+ VirtViewerApp *self = VIRT_VIEWER_APP(gapp);
+ gboolean ret = FALSE;
+ gint argc = g_strv_length(*args);
+ GError *error = NULL;
+ GOptionContext *context = g_option_context_new(NULL);
+ GOptionGroup *group = g_option_group_new("virt-viewer", NULL, NULL, gapp, NULL);
+
+ *status = 0;
+ g_option_context_set_main_group(context, group);
+ VIRT_VIEWER_APP_GET_CLASS(self)->add_option_entries(self, context, group);
+
+ g_option_context_add_group(context, gtk_get_option_group(TRUE));
+
+#ifdef HAVE_GTK_VNC
+ g_option_context_add_group(context, vnc_display_get_option_group());
+#endif
+
+#ifdef HAVE_SPICE_GTK
+ g_option_context_add_group(context, spice_get_option_group());
+#endif
+
+ if (!g_option_context_parse(context, &argc, args, &error)) {
+ if (error != NULL) {
+ g_printerr(_("%s\n"), error->message);
+ g_error_free(error);
+ }
+
+ *status = 1;
+ ret = TRUE;
+ goto end;
+ }
+
+ if (opt_version) {
+ g_print(_("%s version %s"), g_get_prgname(), VERSION BUILDID);
+#ifdef REMOTE_VIEWER_OS_ID
+ g_print(" (OS ID: %s)", REMOTE_VIEWER_OS_ID);
+#endif
+ g_print("\n");
+ ret = TRUE;
+ }
+
+end:
+ g_option_context_free(context);
+ return ret;
}
static void
virt_viewer_app_class_init (VirtViewerAppClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GApplicationClass *g_app_class = G_APPLICATION_CLASS(klass);
g_type_class_add_private (klass, sizeof (VirtViewerAppPrivate));
- object_class->constructed = virt_viewer_app_constructed;
object_class->get_property = virt_viewer_app_get_property;
object_class->set_property = virt_viewer_app_set_property;
object_class->dispose = virt_viewer_app_dispose;
+ g_app_class->local_command_line = virt_viewer_app_local_command_line;
+ g_app_class->startup = virt_viewer_app_on_application_startup;
+ g_app_class->command_line = NULL; /* inhibit GApplication default handler */
+
klass->start = virt_viewer_app_default_start;
klass->initial_connect = virt_viewer_app_default_initial_connect;
klass->activate = virt_viewer_app_default_activate;
klass->deactivated = virt_viewer_app_default_deactivated;
klass->open_connection = virt_viewer_app_default_open_connection;
+ klass->add_option_entries = virt_viewer_app_add_option_entries;
g_object_class_install_property(object_class,
PROP_VERBOSE,
@@ -2014,28 +2081,6 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass)
G_PARAM_READABLE |
G_PARAM_WRITABLE |
G_PARAM_STATIC_STRINGS));
-
- signals[SIGNAL_WINDOW_ADDED] =
- g_signal_new("window-added",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(VirtViewerAppClass, window_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- signals[SIGNAL_WINDOW_REMOVED] =
- g_signal_new("window-removed",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(VirtViewerAppClass, window_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
}
void
@@ -2575,10 +2620,14 @@ option_kiosk_quit(G_GNUC_UNUSED const gchar *option_name,
return FALSE;
}
-GOptionGroup*
-virt_viewer_app_get_option_group(void)
+static void
+virt_viewer_app_add_option_entries(G_GNUC_UNUSED VirtViewerApp *self,
+ G_GNUC_UNUSED GOptionContext *context,
+ GOptionGroup *group)
{
static const GOptionEntry options [] = {
+ { "version", 'V', 0, G_OPTION_ARG_NONE, &opt_version,
+ N_("Display version information"), NULL },
{ "zoom", 'z', 0, G_OPTION_ARG_INT, &opt_zoom,
N_("Zoom level of window, in percentage"), "ZOOM" },
{ "full-screen", 'f', 0, G_OPTION_ARG_NONE, &opt_fullscreen,
@@ -2595,11 +2644,8 @@ virt_viewer_app_get_option_group(void)
N_("Display debugging information"), NULL },
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
};
- GOptionGroup *group;
- group = g_option_group_new("virt-viewer", NULL, NULL, NULL, NULL);
- g_option_group_add_entries(group, options);
- return group;
+ g_option_group_add_entries(group, options);
}
gboolean virt_viewer_app_get_session_cancelled(VirtViewerApp *self)