mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/virt-viewer
synced 2025-12-29 08:42:19 +00:00
Split VirtViewerApp window into VirtViewerWindow
This commit is contained in:
parent
dd9c85a32d
commit
c7ad98333d
@ -20,6 +20,8 @@ virt_viewer_SOURCES = \
|
||||
virt-viewer-session-vnc.h virt-viewer-session-vnc.c \
|
||||
virt-viewer-display.h virt-viewer-display.c \
|
||||
virt-viewer-display-vnc.h virt-viewer-display-vnc.c \
|
||||
virt-viewer-notebook.h virt-viewer-notebook.c \
|
||||
virt-viewer-window.h virt-viewer-window.c \
|
||||
view/autoDrawer.c \
|
||||
view/autoDrawer.h \
|
||||
view/drawer.c \
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,7 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "virt-viewer-util.h"
|
||||
#include "virt-viewer-window.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -52,6 +53,8 @@ typedef struct {
|
||||
|
||||
GType virt_viewer_app_get_type (void);
|
||||
|
||||
void virt_viewer_app_quit(VirtViewerApp *self);
|
||||
VirtViewerWindow* virt_viewer_app_get_main_window(VirtViewerApp *self);
|
||||
void virt_viewer_app_set_debug(gboolean debug);
|
||||
gboolean virt_viewer_app_start(VirtViewerApp *app, gboolean fullscreen);
|
||||
void virt_viewer_app_trace(VirtViewerApp *self, const char *fmt, ...);
|
||||
|
||||
@ -121,14 +121,18 @@ virt_viewer_display_spice_new(SpiceChannel *channel,
|
||||
SpiceDisplay *display)
|
||||
{
|
||||
VirtViewerDisplaySpice *self;
|
||||
gint channelid;
|
||||
|
||||
self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_SPICE, NULL);
|
||||
g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), NULL);
|
||||
g_return_val_if_fail(SPICE_IS_DISPLAY(display), NULL);
|
||||
|
||||
self->priv->channel = channel;
|
||||
self->priv->display = display;
|
||||
g_object_get(channel, "channel-id", &channelid, NULL);
|
||||
|
||||
g_object_ref(channel);
|
||||
g_object_ref(display);
|
||||
self = g_object_new(VIRT_VIEWER_TYPE_DISPLAY_SPICE,
|
||||
"nth-display", channelid,
|
||||
NULL);
|
||||
self->priv->channel = g_object_ref(channel);
|
||||
self->priv->display = g_object_ref(display);
|
||||
|
||||
g_signal_connect(channel, "display-primary-create",
|
||||
G_CALLBACK(virt_viewer_display_spice_primary_create), self);
|
||||
|
||||
@ -38,6 +38,7 @@ struct _VirtViewerDisplayPrivate
|
||||
guint desktopHeight;
|
||||
guint zoom_level;
|
||||
gboolean zoom;
|
||||
gint nth_display;
|
||||
};
|
||||
|
||||
static void virt_viewer_display_size_request(GtkWidget *widget,
|
||||
@ -68,6 +69,7 @@ enum {
|
||||
|
||||
PROP_DESKTOP_WIDTH,
|
||||
PROP_DESKTOP_HEIGHT,
|
||||
PROP_NTH_DISPLAY,
|
||||
PROP_ZOOM,
|
||||
PROP_ZOOM_LEVEL,
|
||||
};
|
||||
@ -124,6 +126,17 @@ virt_viewer_display_class_init(VirtViewerDisplayClass *class)
|
||||
100,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_NTH_DISPLAY,
|
||||
g_param_spec_int("nth-display",
|
||||
"Nth display",
|
||||
"Nth display",
|
||||
0,
|
||||
G_MAXINT32,
|
||||
0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
|
||||
g_signal_new("display-pointer-grab",
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
@ -218,7 +231,9 @@ virt_viewer_display_set_property(GObject *object,
|
||||
priv->desktopWidth,
|
||||
g_value_get_int(value));
|
||||
break;
|
||||
|
||||
case PROP_NTH_DISPLAY:
|
||||
priv->nth_display = g_value_get_int(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -241,6 +256,9 @@ virt_viewer_display_get_property(GObject *object,
|
||||
case PROP_DESKTOP_HEIGHT:
|
||||
g_value_set_int(value, priv->desktopHeight);
|
||||
break;
|
||||
case PROP_NTH_DISPLAY:
|
||||
g_value_set_int(value, priv->nth_display);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
||||
135
src/virt-viewer-notebook.c
Normal file
135
src/virt-viewer-notebook.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Virt Viewer: A virtual machine console viewer
|
||||
*
|
||||
* Copyright (C) 2007-2009 Red Hat,
|
||||
* Copyright (C) 2009 Daniel P. Berrange
|
||||
* Copyright (C) 2010 Marc-André Lureau
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
#include "virt-viewer-notebook.h"
|
||||
#include "virt-viewer-util.h"
|
||||
|
||||
G_DEFINE_TYPE (VirtViewerNotebook, virt_viewer_notebook, GTK_TYPE_NOTEBOOK)
|
||||
|
||||
#define GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebookPrivate))
|
||||
|
||||
typedef struct _VirtViewerNotebookPrivate VirtViewerNotebookPrivate;
|
||||
|
||||
struct _VirtViewerNotebookPrivate {
|
||||
GtkWidget *status;
|
||||
};
|
||||
|
||||
static void
|
||||
virt_viewer_notebook_get_property (GObject *object, guint property_id,
|
||||
GValue *value G_GNUC_UNUSED, GParamSpec *pspec)
|
||||
{
|
||||
switch (property_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_notebook_set_property (GObject *object, guint property_id,
|
||||
const GValue *value G_GNUC_UNUSED, GParamSpec *pspec)
|
||||
{
|
||||
switch (property_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_notebook_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (virt_viewer_notebook_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_notebook_class_init (VirtViewerNotebookClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (VirtViewerNotebookPrivate));
|
||||
|
||||
object_class->get_property = virt_viewer_notebook_get_property;
|
||||
object_class->set_property = virt_viewer_notebook_set_property;
|
||||
object_class->dispose = virt_viewer_notebook_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_notebook_init (VirtViewerNotebook *self)
|
||||
{
|
||||
VirtViewerNotebookPrivate *priv;
|
||||
GdkColor color;
|
||||
|
||||
self->priv = GET_PRIVATE(self);
|
||||
priv = self->priv;
|
||||
|
||||
priv->status = gtk_label_new("");
|
||||
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(self), FALSE);
|
||||
gtk_notebook_set_show_border(GTK_NOTEBOOK(self), FALSE);
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(self), priv->status, NULL);
|
||||
gdk_color_parse("white", &color);
|
||||
gtk_widget_modify_fg(priv->status, GTK_STATE_NORMAL, &color);
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_notebook_show_status(VirtViewerNotebook *self, const gchar *text)
|
||||
{
|
||||
VirtViewerNotebookPrivate *priv;
|
||||
|
||||
DEBUG_LOG("notebook show status %p", self);
|
||||
g_return_if_fail(VIRT_VIEWER_IS_NOTEBOOK(self));
|
||||
|
||||
priv = self->priv;
|
||||
gtk_label_set_text(GTK_LABEL(priv->status), text);
|
||||
gtk_notebook_set_current_page(GTK_NOTEBOOK(self), 0);
|
||||
gtk_widget_show_all(GTK_WIDGET(self));
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_notebook_show_display(VirtViewerNotebook *self)
|
||||
{
|
||||
GtkWidget *display;
|
||||
|
||||
DEBUG_LOG("notebook show display %p", self);
|
||||
g_return_if_fail(VIRT_VIEWER_IS_NOTEBOOK(self));
|
||||
|
||||
display = gtk_notebook_get_nth_page(GTK_NOTEBOOK(self), 1);
|
||||
g_warn_if_fail(display != NULL);
|
||||
|
||||
gtk_notebook_set_current_page(GTK_NOTEBOOK(self), 1);
|
||||
gtk_widget_show_all(GTK_WIDGET(self));
|
||||
}
|
||||
|
||||
VirtViewerNotebook*
|
||||
virt_viewer_notebook_new (void)
|
||||
{
|
||||
return g_object_new (VIRT_VIEWER_TYPE_NOTEBOOK, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
77
src/virt-viewer-notebook.h
Normal file
77
src/virt-viewer-notebook.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Virt Viewer: A virtual machine console viewer
|
||||
*
|
||||
* Copyright (C) 2007-2009 Red Hat,
|
||||
* Copyright (C) 2009 Daniel P. Berrange
|
||||
* Copyright (C) 2010 Marc-André Lureau
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
#ifndef _VIRT_VIEWER_NOTEBOOK
|
||||
#define _VIRT_VIEWER_NOTEBOOK
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define VIRT_VIEWER_TYPE_NOTEBOOK virt_viewer_notebook_get_type()
|
||||
|
||||
#define VIRT_VIEWER_NOTEBOOK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebook))
|
||||
|
||||
#define VIRT_VIEWER_NOTEBOOK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebookClass))
|
||||
|
||||
#define VIRT_VIEWER_IS_NOTEBOOK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_NOTEBOOK))
|
||||
|
||||
#define VIRT_VIEWER_IS_NOTEBOOK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_NOTEBOOK))
|
||||
|
||||
#define VIRT_VIEWER_NOTEBOOK_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_NOTEBOOK, VirtViewerNotebookClass))
|
||||
|
||||
typedef struct _VirtViewerNotebookPrivate VirtViewerNotebookPrivate;
|
||||
|
||||
typedef struct {
|
||||
GtkNotebook parent;
|
||||
VirtViewerNotebookPrivate *priv;
|
||||
} VirtViewerNotebook;
|
||||
|
||||
typedef struct {
|
||||
GtkNotebookClass parent_class;
|
||||
} VirtViewerNotebookClass;
|
||||
|
||||
GType virt_viewer_notebook_get_type (void);
|
||||
|
||||
VirtViewerNotebook* virt_viewer_notebook_new (void);
|
||||
void virt_viewer_notebook_show_status(VirtViewerNotebook *nb, const gchar *text);
|
||||
void virt_viewer_notebook_show_display(VirtViewerNotebook *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _VIRT_VIEWER_NOTEBOOK */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
891
src/virt-viewer-window.c
Normal file
891
src/virt-viewer-window.c
Normal file
@ -0,0 +1,891 @@
|
||||
/*
|
||||
* Virt Viewer: A virtual machine console viewer
|
||||
*
|
||||
* Copyright (C) 2007-2009 Red Hat,
|
||||
* Copyright (C) 2009 Daniel P. Berrange
|
||||
* Copyright (C) 2010 Marc-André Lureau
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "virt-viewer-window.h"
|
||||
#include "virt-viewer-app.h"
|
||||
#include "virt-viewer-util.h"
|
||||
#include "view/autoDrawer.h"
|
||||
|
||||
/* Signal handlers for main window (move in a VirtViewerMainWindow?) */
|
||||
void virt_viewer_window_menu_view_zoom_out(GtkWidget *menu, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_view_zoom_in(GtkWidget *menu, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_view_zoom_reset(GtkWidget *menu, VirtViewerWindow *self);
|
||||
void virt_viewer_window_delete(GtkWidget *src, void *dummy, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_file_quit(GtkWidget *src, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_help_about(GtkWidget *menu, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_view_fullscreen(GtkWidget *menu, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_view_resize(GtkWidget *menu, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_send(GtkWidget *menu, VirtViewerWindow *self);
|
||||
void virt_viewer_window_menu_file_screenshot(GtkWidget *menu, VirtViewerWindow *self);
|
||||
|
||||
/* Internal methods */
|
||||
static void virt_viewer_window_enable_modifiers(VirtViewerWindow *self);
|
||||
static void virt_viewer_window_disable_modifiers(VirtViewerWindow *self);
|
||||
static void virt_viewer_window_resize(VirtViewerWindow *self);
|
||||
static void virt_viewer_window_toolbar_setup(VirtViewerWindow *self);
|
||||
static gboolean window_state_cb(GtkWidget *widget, GdkEventWindowState *event, gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (VirtViewerWindow, virt_viewer_window, G_TYPE_OBJECT)
|
||||
|
||||
#define GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindowPrivate))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_WINDOW,
|
||||
PROP_DISPLAY,
|
||||
PROP_SUBTITLE,
|
||||
PROP_CONTAINER,
|
||||
PROP_APP,
|
||||
};
|
||||
|
||||
enum menuNums {
|
||||
FILE_MENU,
|
||||
VIEW_MENU,
|
||||
SEND_KEY_MENU,
|
||||
HELP_MENU,
|
||||
LAST_MENU // sentinel
|
||||
};
|
||||
|
||||
struct _VirtViewerWindowPrivate {
|
||||
VirtViewerApp *app;
|
||||
GtkContainer *container; /* if any, then there is no window */
|
||||
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *window;
|
||||
GtkWidget *layout;
|
||||
GtkWidget *toolbar;
|
||||
VirtViewerNotebook *notebook;
|
||||
VirtViewerDisplay *display;
|
||||
|
||||
gboolean accel_enabled;
|
||||
GValue accel_setting;
|
||||
GSList *accel_list;
|
||||
int accel_menu_sig[LAST_MENU];
|
||||
gboolean grabbed;
|
||||
|
||||
gint zoomlevel;
|
||||
gboolean auto_resize;
|
||||
gboolean fullscreen;
|
||||
gchar *subtitle;
|
||||
};
|
||||
|
||||
#if GTK_CHECK_VERSION(3, 0, 0)
|
||||
#define GDK_Control_L GDK_KEY_Control_L
|
||||
#define GDK_Alt_L GDK_KEY_Alt_L
|
||||
#define GDK_Delete GDK_KEY_Delete
|
||||
#define GDK_BackSpace GDK_KEY_BackSpace
|
||||
#define GDK_Print GDK_KEY_Print
|
||||
#define GDK_F1 GDK_KEY_F1
|
||||
#define GDK_F2 GDK_KEY_F2
|
||||
#define GDK_F3 GDK_KEY_F3
|
||||
#define GDK_F4 GDK_KEY_F4
|
||||
#define GDK_F5 GDK_KEY_F5
|
||||
#define GDK_F6 GDK_KEY_F6
|
||||
#define GDK_F7 GDK_KEY_F7
|
||||
#define GDK_F8 GDK_KEY_F8
|
||||
#define GDK_F9 GDK_KEY_F9
|
||||
#define GDK_F10 GDK_KEY_F10
|
||||
#define GDK_F11 GDK_KEY_F11
|
||||
#define GDK_F12 GDK_KEY_F12
|
||||
#endif
|
||||
|
||||
static void
|
||||
virt_viewer_window_get_property (GObject *object, guint property_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = VIRT_VIEWER_WINDOW(object)->priv;
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_SUBTITLE:
|
||||
g_value_set_string(value, priv->subtitle);
|
||||
break;
|
||||
|
||||
case PROP_WINDOW:
|
||||
g_value_set_object(value, priv->window);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object(value, priv->display);
|
||||
break;
|
||||
|
||||
case PROP_CONTAINER:
|
||||
g_value_set_object(value, priv->container);
|
||||
break;
|
||||
|
||||
case PROP_APP:
|
||||
g_value_set_object(value, priv->app);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_set_property (GObject *object, guint property_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = VIRT_VIEWER_WINDOW(object)->priv;
|
||||
|
||||
switch (property_id) {
|
||||
case PROP_SUBTITLE:
|
||||
g_free(priv->subtitle);
|
||||
priv->subtitle = g_value_dup_string(value);
|
||||
break;
|
||||
|
||||
case PROP_CONTAINER:
|
||||
g_return_if_fail(priv->container == NULL);
|
||||
priv->container = g_value_dup_object(value);
|
||||
break;
|
||||
|
||||
case PROP_APP:
|
||||
g_return_if_fail(priv->app == NULL);
|
||||
priv->app = g_value_dup_object(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_dispose (GObject *object)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = VIRT_VIEWER_WINDOW(object)->priv;
|
||||
G_OBJECT_CLASS (virt_viewer_window_parent_class)->dispose (object);
|
||||
|
||||
if (priv->display) {
|
||||
g_object_unref(priv->display);
|
||||
priv->display = NULL;
|
||||
}
|
||||
|
||||
if (priv->app) {
|
||||
g_object_unref(priv->app);
|
||||
priv->app = NULL;
|
||||
}
|
||||
|
||||
g_free(priv->subtitle);
|
||||
priv->subtitle = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_class_init (VirtViewerWindowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (VirtViewerWindowPrivate));
|
||||
|
||||
object_class->get_property = virt_viewer_window_get_property;
|
||||
object_class->set_property = virt_viewer_window_set_property;
|
||||
object_class->dispose = virt_viewer_window_dispose;
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_SUBTITLE,
|
||||
g_param_spec_string("subtitle",
|
||||
"Subtitle",
|
||||
"Window subtitle",
|
||||
"",
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_WINDOW,
|
||||
g_param_spec_object("window",
|
||||
"Window",
|
||||
"GtkWindow",
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_DISPLAY,
|
||||
g_param_spec_object("display",
|
||||
"Display",
|
||||
"VirtDisplay",
|
||||
VIRT_VIEWER_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_CONTAINER,
|
||||
g_param_spec_object("container",
|
||||
"Container",
|
||||
"Container widget",
|
||||
VIRT_VIEWER_TYPE_DISPLAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_APP,
|
||||
g_param_spec_object("app",
|
||||
"App",
|
||||
"VirtViewerApp",
|
||||
VIRT_VIEWER_TYPE_APP,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_init (VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *menu;
|
||||
GdkColor color;
|
||||
GSList *accels;
|
||||
|
||||
self->priv = GET_PRIVATE(self);
|
||||
priv = self->priv;
|
||||
|
||||
priv->auto_resize = TRUE;
|
||||
g_value_init(&priv->accel_setting, G_TYPE_STRING);
|
||||
|
||||
priv->notebook = virt_viewer_notebook_new();
|
||||
priv->builder = virt_viewer_util_load_ui("virt-viewer.xml");
|
||||
|
||||
menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "menu-view-resize"));
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
|
||||
|
||||
gtk_builder_connect_signals(priv->builder, self);
|
||||
|
||||
vbox = GTK_WIDGET(gtk_builder_get_object(priv->builder, "viewer-box"));
|
||||
virt_viewer_window_toolbar_setup(self);
|
||||
|
||||
gtk_box_pack_end(GTK_BOX(vbox), priv->layout, TRUE, TRUE, 0);
|
||||
gdk_color_parse("black", &color);
|
||||
gtk_widget_modify_bg(priv->layout, GTK_STATE_NORMAL, &color);
|
||||
|
||||
priv->window = GTK_WIDGET(gtk_builder_get_object(priv->builder, "viewer"));
|
||||
virt_viewer_window_update_title(self);
|
||||
gtk_window_set_resizable(GTK_WINDOW(priv->window), TRUE);
|
||||
#if GTK_CHECK_VERSION(3, 0, 0)
|
||||
gtk_window_set_has_resize_grip(GTK_WINDOW(priv->window), FALSE);
|
||||
#endif
|
||||
priv->accel_enabled = TRUE;
|
||||
|
||||
accels = gtk_accel_groups_from_object(G_OBJECT(priv->window));
|
||||
for ( ; accels ; accels = accels->next) {
|
||||
priv->accel_list = g_slist_append(priv->accel_list, accels->data);
|
||||
g_object_ref(G_OBJECT(accels->data));
|
||||
}
|
||||
g_signal_connect(G_OBJECT(priv->window), "window-state-event", G_CALLBACK(window_state_cb), self);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_desktop_resize(VirtViewerDisplay *display G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
if (priv->auto_resize && priv->window && !priv->fullscreen)
|
||||
virt_viewer_window_resize(self);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_view_zoom_out(GtkWidget *menu G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
if (priv->zoomlevel > 10)
|
||||
priv->zoomlevel -= 10;
|
||||
|
||||
if (!priv->display)
|
||||
return;
|
||||
|
||||
gtk_window_resize(GTK_WINDOW(priv->window), 1, 1);
|
||||
if (priv->display)
|
||||
virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(priv->display), priv->zoomlevel);
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_view_zoom_in(GtkWidget *menu G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
if (priv->zoomlevel < 400)
|
||||
priv->zoomlevel += 10;
|
||||
|
||||
if (!priv->display)
|
||||
return;
|
||||
|
||||
gtk_window_resize(GTK_WINDOW(priv->window), 1, 1);
|
||||
if (priv->display)
|
||||
virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(priv->display), priv->zoomlevel);
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_view_zoom_reset(GtkWidget *menu G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
gtk_window_resize(GTK_WINDOW(priv->window), 1, 1);
|
||||
priv->zoomlevel = 100;
|
||||
|
||||
if (priv->display)
|
||||
virt_viewer_display_set_zoom_level(VIRT_VIEWER_DISPLAY(priv->display), priv->zoomlevel);
|
||||
}
|
||||
|
||||
/*
|
||||
* This code attempts to resize the top level window to be large enough
|
||||
* to contain the entire display desktop at 1:1 ratio. If the local desktop
|
||||
* isn't large enough that it goes as large as possible and lets the display
|
||||
* scale down to fit, maintaining aspect ratio
|
||||
*/
|
||||
static void
|
||||
virt_viewer_window_resize(VirtViewerWindow *self)
|
||||
{
|
||||
GdkRectangle fullscreen;
|
||||
GdkScreen *screen;
|
||||
int width, height;
|
||||
double desktopAspect;
|
||||
double screenAspect;
|
||||
guint desktopWidth;
|
||||
guint desktopHeight;
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
DEBUG_LOG("Preparing main window resize");
|
||||
if (!priv->display) {
|
||||
DEBUG_LOG("Skipping inactive resize");
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_window_resize(GTK_WINDOW(priv->window), 1, 1);
|
||||
|
||||
virt_viewer_display_get_desktop_size(VIRT_VIEWER_DISPLAY(priv->display),
|
||||
&desktopWidth, &desktopHeight);
|
||||
|
||||
screen = gtk_widget_get_screen(priv->window);
|
||||
gdk_screen_get_monitor_geometry(screen,
|
||||
gdk_screen_get_monitor_at_window
|
||||
(screen, gtk_widget_get_window(priv->window)),
|
||||
&fullscreen);
|
||||
|
||||
desktopAspect = (double)desktopWidth / (double)desktopHeight;
|
||||
screenAspect = (double)(fullscreen.width - 128) / (double)(fullscreen.height - 128);
|
||||
|
||||
if ((desktopWidth > (fullscreen.width - 128)) ||
|
||||
(desktopHeight > (fullscreen.height - 128))) {
|
||||
/* Doesn't fit native res, so go as large as possible
|
||||
maintaining aspect ratio */
|
||||
if (screenAspect > desktopAspect) {
|
||||
width = desktopHeight * desktopAspect;
|
||||
height = desktopHeight;
|
||||
} else {
|
||||
width = desktopWidth;
|
||||
height = desktopWidth / desktopAspect;
|
||||
}
|
||||
} else {
|
||||
width = desktopWidth;
|
||||
height = desktopHeight;
|
||||
}
|
||||
|
||||
DEBUG_LOG("Decided todo %dx%d (desktop is %dx%d, fullscreen is %dx%d",
|
||||
width, height, desktopWidth, desktopHeight,
|
||||
fullscreen.width, fullscreen.height);
|
||||
|
||||
virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(priv->display),
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_leave_fullscreen(VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "top-menu"));
|
||||
|
||||
if (!priv->fullscreen)
|
||||
return;
|
||||
priv->fullscreen = FALSE;
|
||||
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), FALSE);
|
||||
gtk_widget_show(menu);
|
||||
gtk_widget_hide(priv->toolbar);
|
||||
gtk_window_unfullscreen(GTK_WINDOW(priv->window));
|
||||
if (priv->auto_resize)
|
||||
virt_viewer_window_resize(self);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_enter_fullscreen(VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "top-menu"));
|
||||
|
||||
if (priv->fullscreen)
|
||||
return;
|
||||
priv->fullscreen = TRUE;
|
||||
gtk_widget_hide(menu);
|
||||
gtk_window_fullscreen(GTK_WINDOW(priv->window));
|
||||
gtk_widget_show(priv->toolbar);
|
||||
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), TRUE);
|
||||
ViewAutoDrawer_Close(VIEW_AUTODRAWER(priv->layout));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_state_cb(GtkWidget *widget G_GNUC_UNUSED, GdkEventWindowState *event,
|
||||
gpointer data)
|
||||
{
|
||||
VirtViewerWindow *self = data;
|
||||
|
||||
if (!(event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN))
|
||||
return TRUE;
|
||||
|
||||
if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
|
||||
virt_viewer_window_enter_fullscreen(self);
|
||||
else
|
||||
virt_viewer_window_leave_fullscreen(self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define MAX_KEY_COMBO 3
|
||||
struct keyComboDef {
|
||||
guint keys[MAX_KEY_COMBO];
|
||||
guint nkeys;
|
||||
const char *label;
|
||||
};
|
||||
|
||||
static const struct keyComboDef keyCombos[] = {
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_Delete }, 3, "Ctrl+Alt+_Del"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_BackSpace }, 3, "Ctrl+Alt+_Backspace"},
|
||||
{ {}, 0, "" },
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F1 }, 3, "Ctrl+Alt+F_1"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F2 }, 3, "Ctrl+Alt+F_2"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F3 }, 3, "Ctrl+Alt+F_3"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F4 }, 3, "Ctrl+Alt+F_4"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_5"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F_6"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F_7"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F_8"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_9"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F1_0"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F11"},
|
||||
{ { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F12"},
|
||||
{ {}, 0, "" },
|
||||
{ { GDK_Print }, 1, "_PrintScreen"},
|
||||
};
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_send(GtkWidget *menu G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
int i;
|
||||
GtkWidget *label = gtk_bin_get_child(GTK_BIN(menu));
|
||||
const char *text = gtk_label_get_label(GTK_LABEL(label));
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS(keyCombos) ; i++) {
|
||||
if (!strcmp(text, keyCombos[i].label)) {
|
||||
DEBUG_LOG("Sending key combo %s", gtk_label_get_text(GTK_LABEL(label)));
|
||||
virt_viewer_display_send_keys(VIRT_VIEWER_DISPLAY(priv->display),
|
||||
keyCombos[i].keys,
|
||||
keyCombos[i].nkeys);
|
||||
return;
|
||||
}
|
||||
}
|
||||
DEBUG_LOG("Failed to find key combo %s", gtk_label_get_text(GTK_LABEL(label)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
virt_viewer_window_ignore_accel(GtkWidget *menu G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self G_GNUC_UNUSED)
|
||||
{
|
||||
/* ignore accelerator */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const char * const menuNames[LAST_MENU] = {
|
||||
"menu-file", "menu-view", "menu-send", "menu-help"
|
||||
};
|
||||
|
||||
void
|
||||
virt_viewer_window_disable_modifiers(VirtViewerWindow *self)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default();
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
GValue empty;
|
||||
GSList *accels;
|
||||
int i;
|
||||
|
||||
if (!priv->window)
|
||||
return;
|
||||
|
||||
if (!priv->accel_enabled)
|
||||
return;
|
||||
|
||||
/* This stops F10 activating menu bar */
|
||||
memset(&empty, 0, sizeof empty);
|
||||
g_value_init(&empty, G_TYPE_STRING);
|
||||
g_object_get_property(G_OBJECT(settings), "gtk-menu-bar-accel", &priv->accel_setting);
|
||||
g_object_set_property(G_OBJECT(settings), "gtk-menu-bar-accel", &empty);
|
||||
|
||||
/* This stops global accelerators like Ctrl+Q == Quit */
|
||||
for (accels = priv->accel_list ; accels ; accels = accels->next) {
|
||||
gtk_window_remove_accel_group(GTK_WINDOW(priv->window), accels->data);
|
||||
}
|
||||
|
||||
/* This stops menu bar shortcuts like Alt+F == File */
|
||||
for (i = 0 ; i < LAST_MENU ; i++) {
|
||||
GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, menuNames[i]));
|
||||
priv->accel_menu_sig[i] =
|
||||
g_signal_connect(menu, "mnemonic-activate",
|
||||
G_CALLBACK(virt_viewer_window_ignore_accel), self);
|
||||
}
|
||||
|
||||
priv->accel_enabled = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_enable_modifiers(VirtViewerWindow *self)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default();
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
GSList *accels;
|
||||
int i;
|
||||
|
||||
if (!priv->window)
|
||||
return;
|
||||
|
||||
if (priv->accel_enabled)
|
||||
return;
|
||||
|
||||
/* This allows F10 activating menu bar */
|
||||
g_object_set_property(G_OBJECT(settings), "gtk-menu-bar-accel", &priv->accel_setting);
|
||||
|
||||
/* This allows global accelerators like Ctrl+Q == Quit */
|
||||
for (accels = priv->accel_list ; accels ; accels = accels->next) {
|
||||
gtk_window_add_accel_group(GTK_WINDOW(priv->window), accels->data);
|
||||
}
|
||||
|
||||
/* This allows menu bar shortcuts like Alt+F == File */
|
||||
for (i = 0 ; i < LAST_MENU ; i++) {
|
||||
GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, menuNames[i]));
|
||||
g_signal_handler_disconnect(menu, priv->accel_menu_sig[i]);
|
||||
}
|
||||
|
||||
priv->accel_enabled = TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virt_viewer_window_delete(GtkWidget *src G_GNUC_UNUSED,
|
||||
void *dummy G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
g_warning("TODO: we might want some other behaviour");
|
||||
virt_viewer_app_quit(self->priv->app);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_file_quit(GtkWidget *src G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
virt_viewer_app_quit(self->priv->app);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virt_viewer_window_toolbar_leave_fullscreen(GtkWidget *button G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
GtkWidget *menu = GTK_WIDGET(gtk_builder_get_object(priv->builder, "menu-view-fullscreen"));
|
||||
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
|
||||
virt_viewer_window_leave_fullscreen(self);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_view_fullscreen(GtkWidget *menu,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
if (!priv->window)
|
||||
return;
|
||||
|
||||
if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu))) {
|
||||
virt_viewer_window_enter_fullscreen(self);
|
||||
} else {
|
||||
virt_viewer_window_leave_fullscreen(self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_view_resize(GtkWidget *menu,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu))) {
|
||||
priv->auto_resize = TRUE;
|
||||
if (!priv->fullscreen)
|
||||
virt_viewer_window_resize(self);
|
||||
} else {
|
||||
priv->auto_resize = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_save_screenshot(VirtViewerWindow *self,
|
||||
const char *file)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
GdkPixbuf *pix = virt_viewer_display_get_pixbuf(VIRT_VIEWER_DISPLAY(priv->display));
|
||||
|
||||
gdk_pixbuf_save(pix, file, "png", NULL,
|
||||
"tEXt::Generator App", PACKAGE, NULL);
|
||||
gdk_pixbuf_unref(pix);
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_file_screenshot(GtkWidget *menu G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
g_return_if_fail(priv->display != NULL);
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new ("Save screenshot",
|
||||
NULL,
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
|
||||
|
||||
//gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), default_folder_for_saving);
|
||||
//gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "Screenshot");
|
||||
|
||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *filename;
|
||||
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||
virt_viewer_window_save_screenshot(self, filename);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_menu_help_about(GtkWidget *menu G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
GtkBuilder *about = virt_viewer_util_load_ui("virt-viewer-about.xml");
|
||||
|
||||
GtkWidget *dialog = GTK_WIDGET(gtk_builder_get_object(about, "about"));
|
||||
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), VERSION);
|
||||
|
||||
gtk_builder_connect_signals(about, self);
|
||||
|
||||
gtk_widget_show_all(dialog);
|
||||
|
||||
g_object_unref(G_OBJECT(about));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virt_viewer_window_toolbar_setup(VirtViewerWindow *self)
|
||||
{
|
||||
GtkWidget *button;
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
priv->toolbar = gtk_toolbar_new();
|
||||
gtk_toolbar_set_show_arrow(GTK_TOOLBAR(priv->toolbar), FALSE);
|
||||
gtk_widget_set_no_show_all(priv->toolbar, TRUE);
|
||||
gtk_toolbar_set_style(GTK_TOOLBAR(priv->toolbar), GTK_TOOLBAR_BOTH_HORIZ);
|
||||
|
||||
/* Close connection */
|
||||
button = GTK_WIDGET(gtk_tool_button_new_from_stock(GTK_STOCK_CLOSE));
|
||||
gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button), _("Disconnect"));
|
||||
gtk_widget_show(GTK_WIDGET(button));
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(priv->toolbar), GTK_TOOL_ITEM (button), 0);
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(gtk_main_quit), NULL);
|
||||
|
||||
/* Leave fullscreen */
|
||||
button = GTK_WIDGET(gtk_tool_button_new_from_stock(GTK_STOCK_LEAVE_FULLSCREEN));
|
||||
gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), _("Leave fullscreen"));
|
||||
gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button), _("Leave fullscreen"));
|
||||
gtk_tool_item_set_is_important(GTK_TOOL_ITEM(button), TRUE);
|
||||
gtk_widget_show(GTK_WIDGET(button));
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(priv->toolbar), GTK_TOOL_ITEM(button), 0);
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(virt_viewer_window_toolbar_leave_fullscreen), self);
|
||||
|
||||
priv->layout = ViewAutoDrawer_New();
|
||||
|
||||
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(priv->layout), FALSE);
|
||||
ViewOvBox_SetOver(VIEW_OV_BOX(priv->layout), priv->toolbar);
|
||||
ViewOvBox_SetUnder(VIEW_OV_BOX(priv->layout), GTK_WIDGET(priv->notebook));
|
||||
ViewAutoDrawer_SetOffset(VIEW_AUTODRAWER(priv->layout), -1);
|
||||
ViewAutoDrawer_SetFill(VIEW_AUTODRAWER(priv->layout), FALSE);
|
||||
ViewAutoDrawer_SetOverlapPixels(VIEW_AUTODRAWER(priv->layout), 1);
|
||||
ViewAutoDrawer_SetNoOverlapPixels(VIEW_AUTODRAWER(priv->layout), 0);
|
||||
}
|
||||
|
||||
VirtViewerNotebook*
|
||||
virt_viewer_window_get_notebook (VirtViewerWindow *self)
|
||||
{
|
||||
return VIRT_VIEWER_NOTEBOOK(self->priv->notebook);
|
||||
}
|
||||
|
||||
GtkWindow*
|
||||
virt_viewer_window_get_window (VirtViewerWindow *self)
|
||||
{
|
||||
return GTK_WINDOW(self->priv->window);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_pointer_grab(VirtViewerDisplay *display G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
priv->grabbed = TRUE;
|
||||
virt_viewer_window_update_title(self);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_pointer_ungrab(VirtViewerDisplay *display G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
|
||||
priv->grabbed = FALSE;
|
||||
virt_viewer_window_update_title(self);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_keyboard_grab(VirtViewerDisplay *display G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
virt_viewer_window_disable_modifiers(self);
|
||||
}
|
||||
|
||||
static void
|
||||
virt_viewer_window_keyboard_ungrab(VirtViewerDisplay *display G_GNUC_UNUSED,
|
||||
VirtViewerWindow *self)
|
||||
{
|
||||
virt_viewer_window_enable_modifiers(self);
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_update_title(VirtViewerWindow *self)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv = self->priv;
|
||||
char *title;
|
||||
const char *subtitle;
|
||||
|
||||
if (priv->grabbed)
|
||||
subtitle = "(Press Ctrl+Alt to release pointer) ";
|
||||
else
|
||||
subtitle = "";
|
||||
|
||||
if (priv->subtitle)
|
||||
title = g_strdup_printf("%s%s - Virt Viewer",
|
||||
subtitle, priv->subtitle);
|
||||
else
|
||||
title = g_strdup("Virt Viewer");
|
||||
|
||||
gtk_window_set_title(GTK_WINDOW(priv->window), title);
|
||||
|
||||
g_free(title);
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_set_display(VirtViewerWindow *self, VirtViewerDisplay *display)
|
||||
{
|
||||
VirtViewerWindowPrivate *priv;
|
||||
|
||||
g_return_if_fail(VIRT_VIEWER_IS_WINDOW(self));
|
||||
g_return_if_fail(display == NULL || VIRT_VIEWER_IS_DISPLAY(display));
|
||||
|
||||
priv = self->priv;
|
||||
if (priv->display) {
|
||||
gtk_notebook_remove_page(GTK_NOTEBOOK(priv->notebook), 1);
|
||||
g_object_unref(priv->display);
|
||||
priv->display = NULL;
|
||||
}
|
||||
|
||||
if (display != NULL) {
|
||||
priv->display = g_object_ref(display);
|
||||
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(priv->notebook), GTK_WIDGET(display), NULL);
|
||||
if (gtk_bin_get_child(GTK_BIN(display)))
|
||||
gtk_widget_realize(GTK_WIDGET(gtk_bin_get_child(GTK_BIN(display))));
|
||||
gtk_widget_show_all(GTK_WIDGET(display));
|
||||
|
||||
g_signal_connect(display, "display-pointer-grab",
|
||||
G_CALLBACK(virt_viewer_window_pointer_grab), self);
|
||||
g_signal_connect(display, "display-pointer-ungrab",
|
||||
G_CALLBACK(virt_viewer_window_pointer_ungrab), self);
|
||||
g_signal_connect(display, "display-keyboard-grab",
|
||||
G_CALLBACK(virt_viewer_window_keyboard_grab), self);
|
||||
g_signal_connect(display, "display-keyboard-ungrab",
|
||||
G_CALLBACK(virt_viewer_window_keyboard_ungrab), self);
|
||||
g_signal_connect(display, "display-desktop-resize",
|
||||
G_CALLBACK(virt_viewer_window_desktop_resize), self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
virt_viewer_window_set_zoom_level(VirtViewerWindow *self, gint zoom_level)
|
||||
{
|
||||
g_return_if_fail(VIRT_VIEWER_IS_WINDOW(self));
|
||||
|
||||
/* FIXME: turn into a dynamic property */
|
||||
self->priv->zoomlevel = zoom_level;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
79
src/virt-viewer-window.h
Normal file
79
src/virt-viewer-window.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Virt Viewer: A virtual machine console viewer
|
||||
*
|
||||
* Copyright (C) 2007-2009 Red Hat,
|
||||
* Copyright (C) 2009 Daniel P. Berrange
|
||||
* Copyright (C) 2010 Marc-André Lureau
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
#ifndef _VIRT_VIEWER_WINDOW
|
||||
#define _VIRT_VIEWER_WINDOW
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "virt-viewer-notebook.h"
|
||||
#include "virt-viewer-display.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define VIRT_VIEWER_TYPE_WINDOW virt_viewer_window_get_type()
|
||||
|
||||
#define VIRT_VIEWER_WINDOW(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindow))
|
||||
|
||||
#define VIRT_VIEWER_WINDOW_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindowClass))
|
||||
|
||||
#define VIRT_VIEWER_IS_WINDOW(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_WINDOW))
|
||||
|
||||
#define VIRT_VIEWER_IS_WINDOW_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_WINDOW))
|
||||
|
||||
#define VIRT_VIEWER_WINDOW_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_WINDOW, VirtViewerWindowClass))
|
||||
|
||||
typedef struct _VirtViewerWindowPrivate VirtViewerWindowPrivate;
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
VirtViewerWindowPrivate *priv;
|
||||
} VirtViewerWindow;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
} VirtViewerWindowClass;
|
||||
|
||||
GType virt_viewer_window_get_type (void);
|
||||
|
||||
GtkWindow* virt_viewer_window_get_window (VirtViewerWindow* window);
|
||||
VirtViewerNotebook* virt_viewer_window_get_notebook (VirtViewerWindow* window);
|
||||
void virt_viewer_window_set_display(VirtViewerWindow *self, VirtViewerDisplay *display);
|
||||
void virt_viewer_window_update_title(VirtViewerWindow *self);
|
||||
void virt_viewer_window_set_zoom_level(VirtViewerWindow *self, gint zoom_level);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _VIRT_VIEWER_WINDOW */
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
@ -532,7 +532,7 @@ virt_viewer_new(const char *uri,
|
||||
app = VIRT_VIEWER_APP(self);
|
||||
priv = self->priv;
|
||||
|
||||
virt_viewer_app_set_zoom_level(app, zoom);
|
||||
virt_viewer_window_set_zoom_level(virt_viewer_app_get_main_window(app), zoom);
|
||||
virt_viewer_app_set_direct(app, direct);
|
||||
|
||||
/* should probably be properties instead */
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<object class="GtkWindow" id="viewer">
|
||||
<property name="default_width">400</property>
|
||||
<property name="default_height">400</property>
|
||||
<signal name="delete_event" handler="virt_viewer_app_delete"/>
|
||||
<signal name="delete_event" handler="virt_viewer_window_delete"/>
|
||||
<child>
|
||||
<object class="GtkVBox" id="viewer-box">
|
||||
<property name="visible">True</property>
|
||||
@ -26,7 +26,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Screenshot</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_file_screenshot"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_screenshot"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -40,7 +40,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_file_quit"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_file_quit"/>
|
||||
<accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK|GDK_SHIFT_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
@ -62,7 +62,7 @@
|
||||
<property name="label" translatable="yes">Full screen</property>
|
||||
<property name="use_underline">True</property>
|
||||
<accelerator key="F11" signal="activate"/>
|
||||
<signal name="toggled" handler="virt_viewer_app_menu_view_fullscreen"/>
|
||||
<signal name="toggled" handler="virt_viewer_window_menu_view_fullscreen"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -80,7 +80,7 @@
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_view_zoom_in"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_in"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -90,7 +90,7 @@
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<accelerator key="minus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_view_zoom_out"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_out"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -105,7 +105,7 @@
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<accelerator key="0" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_view_zoom_reset"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_view_zoom_reset"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -117,7 +117,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Automatically resize</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="toggled" handler="virt_viewer_app_menu_view_resize"/>
|
||||
<signal name="toggled" handler="virt_viewer_window_menu_view_resize"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -137,7 +137,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+_Del</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -145,7 +145,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+_Backspace</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -158,7 +158,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_1</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -166,7 +166,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_2</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -174,7 +174,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_3</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -182,7 +182,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_4</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -190,7 +190,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_5</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -198,7 +198,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_6</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -206,7 +206,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_7</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -214,7 +214,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_8</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -222,7 +222,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F_9</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -230,7 +230,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F1_0</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -238,7 +238,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F11</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -246,7 +246,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Ctrl+Alt+F12</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -259,7 +259,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_PrintScreen</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_send"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_send"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -280,7 +280,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="virt_viewer_app_menu_help_about"/>
|
||||
<signal name="activate" handler="virt_viewer_window_menu_help_about"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user