diff --git a/src/interface.cpp b/src/interface.cpp
index fa41e5898bbe81268ce036ee0cab0ab34b375bfb..ea08f170c65b0cf4c14a69e53a6f3231faf0f927 100644 (file)
--- a/src/interface.cpp
+++ b/src/interface.cpp
/* forward declaration */
static gint sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view);
+static void sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop*desktop);
+
/* Drag and Drop */
typedef enum {
sp_ui_menu_item_set_name /* set_name */
};
+static const int MIN_ONSCREEN_DISTANCE = 50;
+
void
sp_create_window(SPViewWidget *vw, gboolean editable)
{
g_return_if_fail(vw != NULL);
g_return_if_fail(SP_IS_VIEW_WIDGET(vw));
- GtkWidget *w = sp_window_new("", TRUE);
+ GtkWidget *win = sp_window_new("", TRUE);
if (editable) {
- g_object_set_data(G_OBJECT(vw), "window", w);
+ g_object_set_data(G_OBJECT(vw), "window", win);
reinterpret_cast<SPDesktopWidget*>(vw)->window =
- static_cast<GtkWindow*>((void*)w);
+ static_cast<GtkWindow*>((void*)win);
}
if (editable) {
- /* fixme: */
- gtk_window_set_default_size((GtkWindow *) w, 640, 480);
- g_object_set_data(G_OBJECT(w), "desktop", SP_DESKTOP_WIDGET(vw)->desktop);
- g_object_set_data(G_OBJECT(w), "desktopwidget", vw);
- g_signal_connect(G_OBJECT(w), "delete_event", G_CALLBACK(sp_ui_delete), vw->view);
- g_signal_connect(G_OBJECT(w), "focus_in_event", G_CALLBACK(sp_desktop_widget_set_focus), vw);
+ SPDesktop* desktop = SP_DESKTOP_WIDGET(vw)->desktop;
+
+ /* fixme: doesn't allow making window any smaller than this */
+ gtk_window_set_default_size((GtkWindow *) win, 640, 480);
+ g_object_set_data(G_OBJECT(win), "desktop", desktop);
+ g_object_set_data(G_OBJECT(win), "desktopwidget", vw);
+ g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(sp_ui_delete), vw->view);
+
+ g_signal_connect(G_OBJECT(win), "window_state_event", G_CALLBACK(sp_ui_state_event), static_cast<SPDesktop*>(vw->view));
+ g_signal_connect(G_OBJECT(win), "focus_in_event", G_CALLBACK(sp_desktop_widget_set_focus), vw);
+
+ gint prefs_geometry =
+ (2==prefs_get_int_attribute("options.savewindowgeometry", "value", 0));
+ if (prefs_geometry) {
+ gint pw = prefs_get_int_attribute("desktop.geometry", "width", -1);
+ gint ph = prefs_get_int_attribute("desktop.geometry", "height", -1);
+ gint px = prefs_get_int_attribute("desktop.geometry", "x", -1);
+ gint py = prefs_get_int_attribute("desktop.geometry", "y", -1);
+ gint full = prefs_get_int_attribute("desktop.geometry", "fullscreen", 0);
+ gint maxed = prefs_get_int_attribute("desktop.geometry", "maximized", 0);
+ if (pw>0 && ph>0) {
+ gint w = MIN(gdk_screen_width(), pw);
+ gint h = MIN(gdk_screen_height(), ph);
+ gint x = MIN(gdk_screen_width() - MIN_ONSCREEN_DISTANCE, px);
+ gint y = MIN(gdk_screen_height() - MIN_ONSCREEN_DISTANCE, py);
+ if (w>0 && h>0 && x>0 && y>0) {
+ x = MIN(gdk_screen_width() - w, x);
+ y = MIN(gdk_screen_height() - h, y);
+ }
+ if (w>0 && h>0) {
+ desktop->setWindowSize(w, h);
+ }
+
+ // Only restore xy for the first window so subsequent windows don't overlap exactly
+ // with first. (Maybe rule should be only restore xy if it's different from xy of
+ // other desktops?)
+
+ // Empirically it seems that active_desktop==this desktop only the first time a
+ // desktop is created.
+ if (x>0 && y>0) {
+ SPDesktop *active_desktop = SP_ACTIVE_DESKTOP;
+ if (active_desktop == desktop || active_desktop==NULL) {
+ desktop->setWindowPosition(NR::Point(x, y));
+ }
+ }
+ }
+ if (maxed) {
+ gtk_window_maximize(GTK_WINDOW(win));
+ }
+ if (full) {
+ gtk_window_fullscreen(GTK_WINDOW(win));
+ }
+ }
+
} else {
- gtk_window_set_policy(GTK_WINDOW(w), TRUE, TRUE, TRUE);
+ gtk_window_set_policy(GTK_WINDOW(win), TRUE, TRUE, TRUE);
}
- gtk_container_add(GTK_CONTAINER(w), GTK_WIDGET(vw));
+ gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(vw));
gtk_widget_show(GTK_WIDGET(vw));
if ( completeDropTargets == 0 || completeDropTargetsCount == 0 )
}
}
- gtk_drag_dest_set(w,
+ gtk_drag_dest_set(win,
GTK_DEST_DEFAULT_ALL,
completeDropTargets,
completeDropTargetsCount,
GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE));
- g_signal_connect(G_OBJECT(w),
+ g_signal_connect(G_OBJECT(win),
"drag_data_received",
G_CALLBACK(sp_ui_drag_data_received),
NULL);
- gtk_widget_show(w);
+ gtk_widget_show(win);
// needed because the first ACTIVATE_DESKTOP was sent when there was no window yet
inkscape_reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop);
@@ -283,6 +335,53 @@ sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view)
return view->shutdown();
}
+/**
+ * sp_ui_state_event
+ *
+ * Called when the window changes its maximize/fullscreen/iconify/pinned state.
+ * Since GTK doesn't have a way to query this state information directly, we
+ * record it for the desktop here, and also possibly trigger a layout.
+ */
+static void
+sp_ui_state_event(GtkWidget *widget, GdkEventWindowState *event, SPDesktop* desktop)
+{
+ // Record the desktop window's state
+ desktop->window_state = event->new_window_state;
+
+ // Layout may differ depending on full-screen mode or not
+ GdkWindowState changed = event->changed_mask;
+ if (changed & (GDK_WINDOW_STATE_FULLSCREEN|GDK_WINDOW_STATE_MAXIMIZED)) {
+ desktop->layoutWidget();
+ }
+/*
+ // debug info
+ g_message("State event desktop=0x%p", desktop);
+ GdkWindowState state = event->new_window_state;
+ GdkWindowState changed = event->changed_mask;
+ if (changed & GDK_WINDOW_STATE_WITHDRAWN) {
+ g_message("-- WIDTHDRAWN = %d", 0!=(state&GDK_WINDOW_STATE_WITHDRAWN));
+ }
+ if (changed & GDK_WINDOW_STATE_ICONIFIED) {
+ g_message("-- ICONIFIED = %d", 0!=(state&GDK_WINDOW_STATE_ICONIFIED));
+ }
+ if (changed & GDK_WINDOW_STATE_MAXIMIZED) {
+ g_message("-- MAXIMIZED = %d", 0!=(state&GDK_WINDOW_STATE_MAXIMIZED));
+ }
+ if (changed & GDK_WINDOW_STATE_STICKY) {
+ g_message("-- STICKY = %d", 0!=(state&GDK_WINDOW_STATE_STICKY));
+ }
+ if (changed & GDK_WINDOW_STATE_FULLSCREEN) {
+ g_message("-- FULLSCREEN = %d", 0!=(state&GDK_WINDOW_STATE_FULLSCREEN));
+ }
+ if (changed & GDK_WINDOW_STATE_ABOVE) {
+ g_message("-- ABOVE = %d", 0!=(state&GDK_WINDOW_STATE_ABOVE));
+ }
+ if (changed & GDK_WINDOW_STATE_BELOW) {
+ g_message("-- BELOW = %d", 0!=(state&GDK_WINDOW_STATE_BELOW));
+ }
+*/
+}
+
/*
* Some day when the right-click menus are ready to start working
* smarter with the verbs, we'll need to change this NULL being
Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view");
gchar const *pref_path;
- if (reinterpret_cast<SPDesktop*>(view)->is_fullscreen)
+ if (reinterpret_cast<SPDesktop*>(view)->is_fullscreen())
pref_path = g_strconcat("fullscreen.", pref, NULL);
else
pref_path = g_strconcat("window.", pref, NULL);
Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view");
gchar const *pref_path;
- if (static_cast<SPDesktop*>(view)->is_fullscreen)
+ if ((static_cast<SPDesktop*>(view))->is_fullscreen())
pref_path = g_strconcat("fullscreen.", pref, NULL);
else
pref_path = g_strconcat("window.", pref, NULL);