Code

Fixes for transient dialogs in win32.
authorgustav_b <gustav_b@users.sourceforge.net>
Sun, 2 Sep 2007 22:31:56 +0000 (22:31 +0000)
committergustav_b <gustav_b@users.sourceforge.net>
Sun, 2 Sep 2007 22:31:56 +0000 (22:31 +0000)
src/ui/dialog/dialog.cpp
src/ui/dialog/dialog.h
src/ui/dialog/dock-behavior.cpp
src/ui/dialog/dock-behavior.h
src/ui/dialog/floating-behavior.cpp
src/ui/widget/dock-item.cpp
src/ui/widget/dock-item.h

index 16124d9f534b31c964e73cf5ecc1f7b1cb29d01f..a0557827cc200220ecc6ddaf22b44680744b308e 100644 (file)
@@ -40,14 +40,22 @@ namespace Inkscape {
 namespace UI {
 namespace Dialog {
 
-static void
+void
 sp_retransientize (Inkscape::Application *inkscape, SPDesktop *desktop, gpointer dlgPtr)
 {
     Dialog *dlg = (Dialog *)dlgPtr;
     dlg->onDesktopActivated (desktop);
 }
 
-static void
+gboolean
+sp_retransientize_again (gpointer dlgPtr)
+{
+    Dialog *dlg = (Dialog *)dlgPtr;
+    dlg->retransientize_suppress = false;
+    return FALSE; // so that it is only called once
+}
+
+void
 sp_dialog_shutdown (GtkObject *object, gpointer dlgPtr)
 {
     Dialog *dlg = (Dialog *)dlgPtr;
index 7530b9a35c31543ec96301a29b707c96442ec210..50b69caa469e574bd6aaaf7cdc7e557c5669c58c 100644 (file)
 #include "dock-behavior.h"
 #include "floating-behavior.h"
 
-namespace Inkscape { class Selection; }
 class SPDesktop;
 
+namespace Inkscape { 
+class Selection; 
+class Application; 
+}
+
 namespace Inkscape {
 namespace UI {
 namespace Dialog {
 
 enum BehaviorType { FLOATING, DOCK };
 
+void sp_retransientize(Inkscape::Application *inkscape, SPDesktop *desktop, gpointer dlgPtr);
+gboolean sp_retransientize_again(gpointer dlgPtr);
+void sp_dialog_shutdown(GtkObject *object, gpointer dlgPtr);
+
 class Dialog {
 public:
 
index 188fc6fb1ad0ec75fba34573b92d84f39997e6d6..5f600db46b8b49e693a3415b9c271a0d5ad8b705 100644 (file)
@@ -23,6 +23,7 @@
 #include "verbs.h"
 #include "dialog.h"
 #include "prefs-utils.h"
+#include "dialogs/dialog-events.h"
 
 #include <gtkmm/invisible.h>
 #include <gtkmm/label.h>
@@ -49,7 +50,12 @@ DockBehavior::DockBehavior(Dialog& dialog) :
     // Connect signals
     _signal_hide_connection = signal_hide().connect(sigc::mem_fun(*this, &Inkscape::UI::Dialog::Behavior::DockBehavior::_onHide));
     signal_response().connect(sigc::mem_fun(_dialog, &Inkscape::UI::Dialog::Dialog::on_response));
-    signal_drag_end().connect(sigc::mem_fun(*this, &Inkscape::UI::Dialog::Behavior::DockBehavior::_onDragEnd));
+    _dock_item.signal_state_changed().connect(sigc::mem_fun(*this, &Inkscape::UI::Dialog::Behavior::DockBehavior::_onStateChanged));
+
+    if (_dock_item.getState() == Widget::DockItem::FLOATING_STATE) {
+        if (Gtk::Window *floating_win = _dock_item.getWindow())
+            sp_transientize(GTK_WIDGET(floating_win->gobj()));
+    }
 }
 
 DockBehavior::~DockBehavior()
@@ -230,12 +236,14 @@ DockBehavior::_onHide()
 }
 
 void
-DockBehavior::_onDragEnd(bool)
+DockBehavior::_onStateChanged(Widget::DockItem::State prev_state, 
+                              Widget::DockItem::State new_state)
 {
-    Widget::DockItem::State prev_state = _dock_item.getPrevState(), state = _dock_item.getState();
-    
-    if (prev_state != state) {
-        prefs_set_int_attribute (_dialog._prefs_path, "state", state);
+    prefs_set_int_attribute (_dialog._prefs_path, "state", new_state);
+
+    if (new_state == Widget::DockItem::FLOATING_STATE) {
+        if (Gtk::Window *floating_win = _dock_item.getWindow())
+            sp_transientize(GTK_WIDGET(floating_win->gobj()));
     }
 }
 
@@ -267,6 +275,54 @@ DockBehavior::onShutdown()
 void
 DockBehavior::onDesktopActivated(SPDesktop *desktop)
 {
+    gint transient_policy = prefs_get_int_attribute_limited ( "options.transientpolicy", "value", 1, 0, 2);
+
+#ifdef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs
+    if (prefs_get_int_attribute ( "options.dialogsontopwin32", "value", 0))
+        transient_policy = 2;
+    else    
+        return;
+#endif        
+
+    if (!transient_policy) 
+        return;
+
+    Gtk::Window *floating_win = _dock_item.getWindow();
+
+    if (floating_win) {
+
+        if (_dialog.retransientize_suppress) {
+            /* if retransientizing of this dialog is still forbidden after
+             * previous call warning turned off because it was confusingly fired
+             * when loading many files from command line
+             */
+
+            // g_warning("Retranzientize aborted! You're switching windows too fast!");
+            return;
+        }
+
+        if (GtkWindow *dialog_win = floating_win->gobj()) {
+
+            _dialog.retransientize_suppress = true; // disallow other attempts to retranzientize this dialog
+            
+            desktop->setWindowTransient (dialog_win);
+
+            /*
+             * This enables "aggressive" transientization,
+             * i.e. dialogs always emerging on top when you switch documents. Note
+             * however that this breaks "click to raise" policy of a window
+             * manager because the switched-to document will be raised at once
+             * (so that its transients also could raise)
+             */
+            if (transient_policy == 2 && ! _dialog._hiddenF12 && !_dialog._user_hidden) {
+                // without this, a transient window not always emerges on top
+                gtk_window_present (dialog_win);
+            }
+        }
+
+        // we're done, allow next retransientizing not sooner than after 120 msec
+        gtk_timeout_add (120, (GtkFunction) sp_retransientize_again, (gpointer) floating_win);
+    }
 }
 
 
index 75bd14be4400c591997a2d8d427b01621bb95c75..01d95dd8ca9b76a242f31557d5f27033d88dbb4a 100644 (file)
@@ -91,8 +91,7 @@ private:
     void _onHide();
     bool _onDeleteEvent(GdkEventAny *event);
     void _onResponse(int response_id);
-    void _onDragBegin();
-    void _onDragEnd(bool cancelled);
+    void _onStateChanged(Widget::DockItem::State prev_state, Widget::DockItem::State new_state);
     bool _onKeyPress(GdkEventKey *event);
 
     sigc::connection _signal_hide_connection;
index b6b6949da05dc880f717b091ceffca9a57f40b69..79f5d08fb257fb8751c8cfeb442f3c137822fdc2 100644 (file)
@@ -29,15 +29,6 @@ namespace UI {
 namespace Dialog {
 namespace Behavior {
 
-static gboolean
-sp_retransientize_again (gpointer dlgPtr)
-{
-    Dialog *dlg = (Dialog *)dlgPtr;
-    dlg->retransientize_suppress = false;
-    return FALSE; // so that it is only called once
-}
-
-
 FloatingBehavior::FloatingBehavior(Dialog& dialog) :
     Behavior(dialog),
     _d (new Gtk::Dialog(_dialog._title))
index 1e232cb4e8acc4c0dd78db574d7e2461871cf747..97f11f56eadd30af91f26f3bfe686075db45a580 100644 (file)
@@ -222,8 +222,8 @@ DockItem::present()
 void 
 DockItem::get_position(int& x, int& y)
 { 
-    if (_getWindow()) {
-        _getWindow()->get_position(x, y);
+    if (getWindow()) {
+        getWindow()->get_position(x, y);
     } else {
         x = _x;
         y = _y;
@@ -392,7 +392,7 @@ DockItem::_onKeyPress(GdkEventKey *event)
 void
 DockItem::_onStateChanged(State prev_state, State new_state)
 {
-    _window = _getWindow();
+    _window = getWindow();
 
     if (new_state == FLOATING_STATE) {
         _window->signal_hide().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onHideWindow));
@@ -411,7 +411,7 @@ DockItem::_onDeleteEvent(GdkEventAny *event)
 
 
 Gtk::Window *
-DockItem::_getWindow()
+DockItem::getWindow()
 {
     g_return_val_if_fail(_gdl_dock_item, 0);
     Gtk::Container *parent = getWidget().get_parent();
index 55a2807678191a6980ee3aac4dd1c7f1163ca59d..f4e403e34ecd55d607357e1b914b445dd4a60ee3 100644 (file)
@@ -70,6 +70,8 @@ public:
     State getPrevState() const;
     Placement getPlacement() const;
 
+    Gtk::Window *getWindow();   //< gives the parent window, if the dock item has one (i.e. it's floating)
+
     void addButton(Gtk::Button *button, int response_id);
 
     void hide();
@@ -131,9 +133,6 @@ private:
     static gboolean _signal_delete_event_callback(GtkWidget *self, GdkEventAny *event, void *data);
     static void _signal_drag_end_callback(GtkWidget* self, gboolean p0, void* data);
 
-    /** Internal helpers */
-    Gtk::Window *_getWindow();   //< gives the parent window, if the dock item has one (i.e. it's floating)
-
     /** In order to emulate a signal_response signal like the one for Gtk::Dialog we inject a new
      * signal into GdlDockItem. This signal will be emitted when a button in the dock item added
      * through the addButton(..., response_id) method, is clicked.