From: buliabyak Date: Mon, 18 Jun 2007 18:52:51 +0000 (+0000) Subject: patch 1734633: option to save window geometry in prefs X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=d75719d68573b3c63dfa38578aca41b5c364c372;p=inkscape.git patch 1734633: option to save window geometry in prefs --- diff --git a/src/desktop.cpp b/src/desktop.cpp index d9f82934c..03373b59e 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -129,7 +129,7 @@ SPDesktop::SPDesktop() : zooms_future( 0 ), dkey( 0 ), number( 0 ), - is_fullscreen( false ), + window_state(0), interaction_disabled_counter( 0 ), waiting_cursor( false ), guides_active( false ), @@ -970,6 +970,36 @@ SPDesktop::scroll_to_point (NR::Point const *p, gdouble autoscrollspeed) return false; } +bool +SPDesktop::is_iconified() +{ + return 0!=(window_state & GDK_WINDOW_STATE_ICONIFIED); +} + +void +SPDesktop::iconify() +{ + _widget->setIconified(); +} + +bool +SPDesktop::is_maximized() +{ + return 0!=(window_state & GDK_WINDOW_STATE_MAXIMIZED); +} + +void +SPDesktop::maximize() +{ + _widget->setMaximized(); +} + +bool +SPDesktop::is_fullscreen() +{ + return 0!=(window_state & GDK_WINDOW_STATE_FULLSCREEN); +} + void SPDesktop::fullscreen() { diff --git a/src/desktop.h b/src/desktop.h index 1ee4d375e..4c255ecbb 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -99,7 +99,7 @@ struct SPDesktop : public Inkscape::UI::View::View GList *zooms_future; unsigned int dkey; unsigned int number; - bool is_fullscreen; + guint window_state; unsigned int interaction_disabled_counter; bool waiting_cursor; @@ -251,6 +251,12 @@ struct SPDesktop : public Inkscape::UI::View::View void toggleGrid(); bool gridsEnabled() { return grids_visible; } + bool is_iconified(); + bool is_maximized(); + bool is_fullscreen(); + + void iconify(); + void maximize(); void fullscreen(); void registerEditWidget (Inkscape::UI::View::EditWidgetInterface *widget) diff --git a/src/interface.cpp b/src/interface.cpp index fa41e5898..ea08f170c 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -69,6 +69,8 @@ using Inkscape::IO::Base64OutputStream; /* 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 { @@ -125,32 +127,82 @@ SPActionEventVector menu_item_event_vector = { 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(vw)->window = - static_cast((void*)w); + static_cast((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(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 ) @@ -184,16 +236,16 @@ sp_create_window(SPViewWidget *vw, gboolean editable) } } - 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 @@ -565,7 +664,7 @@ checkitem_toggled(GtkCheckMenuItem *menuitem, gpointer user_data) Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); gchar const *pref_path; - if (reinterpret_cast(view)->is_fullscreen) + if (reinterpret_cast(view)->is_fullscreen()) pref_path = g_strconcat("fullscreen.", pref, NULL); else pref_path = g_strconcat("window.", pref, NULL); @@ -585,7 +684,7 @@ checkitem_update(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); gchar const *pref_path; - if (static_cast(view)->is_fullscreen) + if ((static_cast(view))->is_fullscreen()) pref_path = g_strconcat("fullscreen.", pref, NULL); else pref_path = g_strconcat("window.", pref, NULL); diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 30ea64dd0..28b1fe018 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -216,6 +216,13 @@ static char const preferences_skeleton[] = "\n" " \n" +" \n" " \n" "\n" " \n" diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index ea0e55dc5..02783207e 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -571,15 +571,16 @@ void SPNamedView::show(SPDesktop *desktop) #define MIN_ONSCREEN_DISTANCE 50 /* - * Restores window geometry from the document settings + * Restores window geometry from the document settings or defaults in prefs */ void sp_namedview_window_from_document(SPDesktop *desktop) { SPNamedView *nv = desktop->namedview; - gint save_geometry = prefs_get_int_attribute("options.savewindowgeometry", "value", 0); + gint geometry_from_file = + (1==prefs_get_int_attribute("options.savewindowgeometry", "value", 0)); - // restore window size and position - if (save_geometry) { + // restore window size and position stored with the document + if (geometry_from_file) { gint w = MIN(gdk_screen_width(), nv->window_width); gint h = MIN(gdk_screen_height(), nv->window_height); gint x = MIN(gdk_screen_width() - MIN_ONSCREEN_DISTANCE, nv->window_x); @@ -588,10 +589,12 @@ void sp_namedview_window_from_document(SPDesktop *desktop) x = MIN(gdk_screen_width() - w, x); y = MIN(gdk_screen_height() - h, y); } - if (w>0 && h>0) + if (w>0 && h>0) { desktop->setWindowSize(w, h); - if (x>0 && y>0) + } + if (x>0 && y>0) { desktop->setWindowPosition(NR::Point(x, y)); + } } // restore zoom and view @@ -641,7 +644,8 @@ void sp_namedview_update_layers_from_document (SPDesktop *desktop) void sp_namedview_document_from_window(SPDesktop *desktop) { - gint save_geometry = prefs_get_int_attribute("options.savewindowgeometry", "value", 0); + gint save_geometry_in_file = + (1==prefs_get_int_attribute("options.savewindowgeometry", "value", 0)); Inkscape::XML::Node *view = SP_OBJECT_REPR(desktop->namedview); NR::Rect const r = desktop->get_display_area(); @@ -653,7 +657,7 @@ void sp_namedview_document_from_window(SPDesktop *desktop) sp_repr_set_svg_double(view, "inkscape:cx", r.midpoint()[NR::X]); sp_repr_set_svg_double(view, "inkscape:cy", r.midpoint()[NR::Y]); - if (save_geometry) { + if (save_geometry_in_file) { gint w, h, x, y; desktop->getWindowGeometry(x, y, w, h); sp_repr_set_int(view, "inkscape:window-width", w); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index f40197cef..5694a3ea3 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -414,7 +414,10 @@ void InkscapePreferences::initPageTools() void InkscapePreferences::initPageWindows() { - _win_save_geom.init ( _("Save window geometry"), "options.savewindowgeometry", "value", true); + _win_save_geom.init ( _("Save and restore window geometry for each document"), "options.savewindowgeometry", "value", 1, true, 0); + _win_save_geom_prefs.init ( _("Remember and use last window's geometry"), "options.savewindowgeometry", "value", 2, false, &_win_save_geom); + _win_save_geom_off.init ( _("Don't save window geometry"), "options.savewindowgeometry", "value", 0, false, &_win_save_geom); + _win_hide_task.init ( _("Dialogs are hidden in taskbar"), "options.dialogsskiptaskbar", "value", true); _win_zoom_resize.init ( _("Zoom when window is resized"), "options.stickyzoom", "value", false); _win_show_close.init ( _("Show close button on dialogs"), "dialogs", "showclose", false); @@ -427,16 +430,14 @@ void InkscapePreferences::initPageWindows() _win_ontop_win32.init ( _("Dialogs stay on top (experimental!)"), "options.dialogsontopwin32", "value", false); #endif + _page_windows.add_group_header( _("Saving window geometry (size and position):")); + _page_windows.add_line( false, "", _win_save_geom_off, "", + _("Let the window manager determine placement of all windows")); + _page_windows.add_line( false, "", _win_save_geom_prefs, "", + _("Remember and use the last window's geometry (saves geometry to user preferences)")); _page_windows.add_line( false, "", _win_save_geom, "", - _("Save the window size and position with each document (only for Inkscape SVG format)")); -#ifndef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs - _page_windows.add_line( false, "", _win_hide_task, "", - _("Whether dialog windows are to be hidden in the window manager taskbar")); -#endif - _page_windows.add_line( false, "", _win_zoom_resize, "", - _("Zoom drawing when document window is resized, to keep the same area visible (this is the default which can be changed in any window using the button above the right scrollbar)")); - _page_windows.add_line( false, "", _win_show_close, "", - _("Whether dialog windows have a close button (requires restart)")); + _("Save and restore window geometry for each document (saves geometry in the document)")); + _page_windows.add_group_header( _("Dialogs on top:")); #ifndef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs _page_windows.add_line( true, "", _win_ontop_none, "", @@ -450,6 +451,15 @@ void InkscapePreferences::initPageWindows() _("Whether dialogs should stay on top of document windows. Read the ReleaseNotes on this issue! (Rightclick the taskbar button and press 'Restore' to bring back a minimized document window)")); #endif + _page_windows.add_group_header( _("Miscellaneous:")); +#ifndef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs + _page_windows.add_line( false, "", _win_hide_task, "", + _("Whether dialog windows are to be hidden in the window manager taskbar")); +#endif + _page_windows.add_line( false, "", _win_zoom_resize, "", + _("Zoom drawing when document window is resized, to keep the same area visible (this is the default which can be changed in any window using the button above the right scrollbar)")); + _page_windows.add_line( false, "", _win_show_close, "", + _("Whether dialog windows have a close button (requires restart)")); this->AddPage(_page_windows, _("Windows"), PREFS_PAGE_WINDOWS); } diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index a08894638..f2a61d1ba 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -117,7 +117,8 @@ protected: PrefSpinButton _t_pencil_tolerance; PrefRadioButton _win_ontop_none, _win_ontop_normal, _win_ontop_agressive; - PrefCheckButton _win_save_geom, _win_hide_task, _win_zoom_resize , _win_show_close; + PrefRadioButton _win_save_geom_off, _win_save_geom, _win_save_geom_prefs; + PrefCheckButton _win_hide_task, _win_zoom_resize , _win_show_close; // FIXME: Temporary Win32 special code to enable transient dialogs #ifdef WIN32 diff --git a/src/ui/view/edit-widget-interface.h b/src/ui/view/edit-widget-interface.h index 7cc0133d3..1df0bff45 100644 --- a/src/ui/view/edit-widget-interface.h +++ b/src/ui/view/edit-widget-interface.h @@ -56,6 +56,12 @@ struct EditWidgetInterface /// Return mouse position in widget virtual NR::Point getPointer() = 0; + /// Make widget iconified + virtual void setIconified() = 0; + + /// Make widget maximized on screen + virtual void setMaximized() = 0; + /// Make widget fill screen and show it if possible. virtual void setFullscreen() = 0; diff --git a/src/ui/view/edit-widget.cpp b/src/ui/view/edit-widget.cpp index bac6854a1..ca298cd5d 100644 --- a/src/ui/view/edit-widget.cpp +++ b/src/ui/view/edit-widget.cpp @@ -1167,6 +1167,18 @@ EditWidget::getPointer() return NR::Point (x, y); } +void +EditWidget::setIconified() +{ + iconify(); +} + +void +EditWidget::setMaximized() +{ + maximize(); +} + void EditWidget::setFullscreen() { @@ -1426,11 +1438,11 @@ EditWidget::toggleRulers() { _top_ruler.hide_all(); _left_ruler.hide_all(); - prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 0); + prefs_set_int_attribute (_desktop->is_fullscreen() ? "fullscreen.rulers" : "window.rulers", "state", 0); } else { _top_ruler.show_all(); _left_ruler.show_all(); - prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 1); + prefs_set_int_attribute (_desktop->is_fullscreen() ? "fullscreen.rulers" : "window.rulers", "state", 1); } } @@ -1441,11 +1453,11 @@ EditWidget::toggleScrollbars() { _bottom_scrollbar.hide_all(); _right_scrollbar.hide_all(); - prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 0); + prefs_set_int_attribute (_desktop->is_fullscreen() ? "fullscreen.scrollbars" : "window.scrollbars", "state", 0); } else { _bottom_scrollbar.show_all(); _right_scrollbar.show_all(); - prefs_set_int_attribute (_desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1); + prefs_set_int_attribute (_desktop->is_fullscreen() ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1); } } diff --git a/src/ui/view/edit-widget.h b/src/ui/view/edit-widget.h index 55a52be4c..bedb94f98 100644 --- a/src/ui/view/edit-widget.h +++ b/src/ui/view/edit-widget.h @@ -106,6 +106,8 @@ public: virtual void setPosition (NR::Point p); virtual void setTransient (void*, int); virtual NR::Point getPointer(); + virtual void setIconified(); + virtual void setMaximized(); virtual void setFullscreen(); virtual bool shutdown(); virtual void destroy(); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 47694518c..9716191ed 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -84,8 +84,6 @@ static void sp_desktop_widget_realize (GtkWidget *widget); static gint sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw); - - static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw); static void sp_desktop_widget_namedview_modified (SPObject *obj, guint flags, SPDesktopWidget *dtw); @@ -555,6 +553,7 @@ bool SPDesktopWidget::shutdown() { g_assert(desktop != NULL); + if (inkscape_is_sole_desktop_for_document(*desktop)) { SPDocument *doc = desktop->doc(); if (sp_document_repr_root(doc)->attribute("sodipodi:modified") != NULL) { @@ -685,6 +684,28 @@ SPDesktopWidget::shutdown() } } + /* Save window geometry to prefs for use as a default. + * Use depends on setting of "options.savewindowgeometry". + * But we save the info here regardless of the setting. + */ + { + gint full = desktop->is_fullscreen() ? 1 : 0; + gint maxed = desktop->is_maximized() ? 1 : 0; + prefs_set_int_attribute("desktop.geometry", "fullscreen", full); + prefs_set_int_attribute("desktop.geometry", "maximized", maxed); + gint w, h, x, y; + desktop->getWindowGeometry(x, y, w, h); + // Don't save geom for maximized windows. It + // just tells you the current maximized size, which is not + // as useful as whatever value it had previously. + if (!maxed && !full) { + prefs_set_int_attribute("desktop.geometry", "width", w); + prefs_set_int_attribute("desktop.geometry", "height", h); + prefs_set_int_attribute("desktop.geometry", "x", x); + prefs_set_int_attribute("desktop.geometry", "y", y); + } + } + return FALSE; } @@ -750,6 +771,8 @@ SPDesktopWidget::letZoomGrabFocus() void SPDesktopWidget::getWindowGeometry (gint &x, gint &y, gint &w, gint &h) { + gboolean vis = GTK_WIDGET_VISIBLE (this); + GtkWindow *window = GTK_WINDOW (gtk_object_get_data (GTK_OBJECT(this), "window")); if (window) { @@ -835,20 +858,68 @@ SPDesktopWidget::warnDialog (gchar* text) return false; } +void +sp_desktop_widget_iconify(SPDesktopWidget *dtw) +{ + GtkWindow *topw = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(dtw->canvas))); + if (GTK_IS_WINDOW(topw)) { + if (dtw->desktop->is_iconified()) { + gtk_window_deiconify(topw); + } else { + gtk_window_iconify(topw); + } + } +} + +void +sp_desktop_widget_maximize(SPDesktopWidget *dtw) +{ + GtkWindow *topw = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(dtw->canvas))); + if (GTK_IS_WINDOW(topw)) { + if (dtw->desktop->is_maximized()) { + gtk_window_unmaximize(topw); + } else { + // Save geometry to prefs before maximizing so that + // something useful is stored there, because GTK doesn't maintain + // a separate non-maximized size. + if (!dtw->desktop->is_iconified() && !dtw->desktop->is_fullscreen()) + { + gint w, h, x, y; + dtw->getWindowGeometry(x, y, w, h); + prefs_set_int_attribute("desktop.geometry", "width", w); + prefs_set_int_attribute("desktop.geometry", "height", h); + prefs_set_int_attribute("desktop.geometry", "x", x); + prefs_set_int_attribute("desktop.geometry", "y", y); + } + gtk_window_maximize(topw); + } + } +} + void sp_desktop_widget_fullscreen(SPDesktopWidget *dtw) { #ifdef HAVE_GTK_WINDOW_FULLSCREEN GtkWindow *topw = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(dtw->canvas))); if (GTK_IS_WINDOW(topw)) { - if (dtw->desktop->is_fullscreen) { - dtw->desktop->is_fullscreen = FALSE; + if (dtw->desktop->is_fullscreen()) { gtk_window_unfullscreen(topw); - sp_desktop_widget_layout (dtw); + // widget layout is triggered by the resulting window_state_event } else { - dtw->desktop->is_fullscreen = TRUE; + // Save geometry to prefs before maximizing so that + // something useful is stored there, because GTK doesn't maintain + // a separate non-maximized size. + if (!dtw->desktop->is_iconified() && !dtw->desktop->is_maximized()) + { + gint w, h, x, y; + dtw->getWindowGeometry(x, y, w, h); + prefs_set_int_attribute("desktop.geometry", "width", w); + prefs_set_int_attribute("desktop.geometry", "height", h); + prefs_set_int_attribute("desktop.geometry", "x", x); + prefs_set_int_attribute("desktop.geometry", "y", y); + } gtk_window_fullscreen(topw); - sp_desktop_widget_layout (dtw); + // widget layout is triggered by the resulting window_state_event } } #endif /* HAVE_GTK_WINDOW_FULLSCREEN */ @@ -860,7 +931,7 @@ sp_desktop_widget_fullscreen(SPDesktopWidget *dtw) void sp_desktop_widget_layout (SPDesktopWidget *dtw) { - bool fullscreen = dtw->desktop->is_fullscreen; + bool fullscreen = dtw->desktop->is_fullscreen(); if (prefs_get_int_attribute (fullscreen ? "fullscreen.menu" : "window.menu", "state", 1) == 0) { gtk_widget_hide_all (dtw->menubar); @@ -1228,11 +1299,11 @@ sp_desktop_widget_toggle_rulers (SPDesktopWidget *dtw) if (GTK_WIDGET_VISIBLE (dtw->hruler)) { gtk_widget_hide_all (dtw->hruler); gtk_widget_hide_all (dtw->vruler); - prefs_set_int_attribute (dtw->desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 0); + prefs_set_int_attribute (dtw->desktop->is_fullscreen() ? "fullscreen.rulers" : "window.rulers", "state", 0); } else { gtk_widget_show_all (dtw->hruler); gtk_widget_show_all (dtw->vruler); - prefs_set_int_attribute (dtw->desktop->is_fullscreen ? "fullscreen.rulers" : "window.rulers", "state", 1); + prefs_set_int_attribute (dtw->desktop->is_fullscreen() ? "fullscreen.rulers" : "window.rulers", "state", 1); } } @@ -1242,11 +1313,11 @@ sp_desktop_widget_toggle_scrollbars (SPDesktopWidget *dtw) if (GTK_WIDGET_VISIBLE (dtw->hscrollbar)) { gtk_widget_hide_all (dtw->hscrollbar); gtk_widget_hide_all (dtw->vscrollbar_box); - prefs_set_int_attribute (dtw->desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 0); + prefs_set_int_attribute (dtw->desktop->is_fullscreen() ? "fullscreen.scrollbars" : "window.scrollbars", "state", 0); } else { gtk_widget_show_all (dtw->hscrollbar); gtk_widget_show_all (dtw->vscrollbar_box); - prefs_set_int_attribute (dtw->desktop->is_fullscreen ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1); + prefs_set_int_attribute (dtw->desktop->is_fullscreen() ? "fullscreen.scrollbars" : "window.scrollbars", "state", 1); } } diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 0514dd393..ef70a21d1 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -35,6 +35,8 @@ void sp_desktop_widget_destroy (SPDesktopWidget* dtw); gint sp_desktop_widget_set_focus(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw); void sp_desktop_widget_show_decorations(SPDesktopWidget *dtw, gboolean show); +void sp_desktop_widget_iconify(SPDesktopWidget *dtw); +void sp_desktop_widget_maximize(SPDesktopWidget *dtw); void sp_desktop_widget_fullscreen(SPDesktopWidget *dtw); void sp_desktop_widget_layout(SPDesktopWidget *dtw); void sp_desktop_widget_update_zoom(SPDesktopWidget *dtw); @@ -127,6 +129,10 @@ struct SPDesktopWidget { { _dtw->setWindowTransient (p, transient_policy); } virtual NR::Point getPointer() { return _dtw->window_get_pointer(); } + virtual void setIconified() + { sp_desktop_widget_iconify (_dtw); } + virtual void setMaximized() + { sp_desktop_widget_maximize (_dtw); } virtual void setFullscreen() { sp_desktop_widget_fullscreen (_dtw); } virtual bool shutdown()