Code

Change desktop coordinate system to match SVG (LP #170049)
authorKrzysztof Kosiński <tweenk.pl@gmail.com>
Sat, 3 Apr 2010 17:07:50 +0000 (19:07 +0200)
committerKrzysztof Kosiński <tweenk.pl@gmail.com>
Sat, 3 Apr 2010 17:07:50 +0000 (19:07 +0200)
packaging/win32/inkscape.nsi
src/display/nr-filter-gaussian.cpp
src/ui/dialog/Makefile_insert
src/ui/dialog/desktop-tracker.cpp [new file with mode: 0644]
src/ui/dialog/desktop-tracker.h [new file with mode: 0644]
src/ui/dialog/fill-and-stroke.cpp
src/ui/dialog/fill-and-stroke.h
src/ui/dialog/glyphs.cpp
src/ui/dialog/glyphs.h

index 5bcd99ee0f8b79ef0928536986152083d5a22592..910717e404b4f94b1ce228fd22d6658d9b3c07d5 100755 (executable)
@@ -991,6 +991,8 @@ Section Uninstall ; do the uninstalling {{{
   Delete $INSTDIR\uninstall.log
   Delete $INSTDIR\uninstall.exe
   ; remove empty directories
+  RMDir $INSTDIR\lib\locale
+  RMDir $INSTDIR\lib
   RMDir $INSTDIR\data
   RMDir $INSTDIR\doc
   RMDir $INSTDIR\modules
index d80782d2009bb7687a11ac811f02558feeee1e7a..9509eaef7f2e4b02e3aeb19c25c5aac57d6252c5 100644 (file)
@@ -345,7 +345,7 @@ filter2D_IIR(PT *const dest, int const dstr1, int const dstr2,
 
 // Filters over 1st dimension
 // Assumes kernel is symmetric
-// scr_len should be size of kernel - 1
+// Kernel should have scr_len+1 elements
 template<typename PT, unsigned int PC>
 static void
 filter2D_FIR(PT *const dst, int const dstr1, int const dstr2,
@@ -377,7 +377,7 @@ filter2D_FIR(PT *const dst, int const dstr1, int const dstr2,
         for ( int c1 = 0 ; c1 < n1 ; c1++ ) {
 
             int const src_disp = src_line + c1 * sstr1;
-            int const dst_disp = dst_line + c1 * sstr1;
+            int const dst_disp = dst_line + c1 * dstr1;
 
             // update history
             for(int i=scr_len; i>0; i--) copy_n(history[i-1], PC, history[i]);
@@ -433,7 +433,7 @@ filter2D_FIR(PT *const dst, int const dstr1, int const dstr2,
                 // optimization: if there was no variation within this point's neighborhood,
                 // skip ahead while we keep seeing the same last_in byte:
                 // blurring flat color would not change it anyway
-                if (different_count <= 1) {
+                if (different_count <= 1) { // note that different_count is at least 1, because last_in is initialized to -1
                     int pos = c1 + 1;
                     int nb_src_disp = src_disp + (1+scr_len)*sstr1 + byte; // src_line + (pos+scr_len) * sstr1 + byte
                     int nb_dst_disp = dst_disp + (1)        *dstr1 + byte; // dst_line + (pos) * sstr1 + byte
@@ -441,7 +441,7 @@ filter2D_FIR(PT *const dst, int const dstr1, int const dstr2,
                         dst[nb_dst_disp] = last_in;
                         pos++;
                         nb_src_disp += sstr1;
-                        nb_dst_disp += sstr1;
+                        nb_dst_disp += dstr1;
                     }
                     skipbuf[byte] = pos;
                 }
@@ -645,6 +645,8 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
             }
         }
     }
+
+    // Resampling (if necessary), goes from in -> out (setting ssin to out if used)
     NRPixBlock *ssin = in;
     if ( resampling ) {
         ssin = out;
@@ -667,6 +669,7 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
         };
     }
 
+    // Horizontal filtering, goes from ssin -> out (ssin might be equal to out, but these algorithms can be used in-place)
     if (use_IIR_x) {
         // Filter variables
         IIRValue b[N+1];  // scaling coefficient + filter coefficients (can be 10.21 fixed point)
@@ -702,9 +705,9 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
         default:
             assert(false);
         };
-    } else if ( scr_len_x > 1 ) { // !use_IIR_x
+    } else if ( scr_len_x > 0 ) { // !use_IIR_x
         // Filter kernel for x direction
-        FIRValue kernel[scr_len_x];
+        FIRValue kernel[scr_len_x+1];
         _make_kernel(kernel, deviation_x);
 
         // Filter (x)
@@ -728,6 +731,7 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
         nr_blit_pixblock_pixblock(out, ssin);
     }
 
+    // Vertical filtering, goes from out -> out
     if (use_IIR_y) {
         // Filter variables
         IIRValue b[N+1];  // scaling coefficient + filter coefficients (can be 10.21 fixed point)
@@ -763,9 +767,9 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
         default:
             assert(false);
         };
-    } else if ( scr_len_y > 1 ) { // !use_IIR_y
+    } else if ( scr_len_y > 0 ) { // !use_IIR_y
         // Filter kernel for y direction
-        FIRValue kernel[scr_len_y];
+        FIRValue kernel[scr_len_y+1];
         _make_kernel(kernel, deviation_y);
 
         // Filter (y)
@@ -791,6 +795,7 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
         delete[] tmpdata[i]; // deleting a nullptr has no effect, so this is safe
     }
 
+    // Upsampling, stores (the upsampled) out using slot.set(_output, ...)
     if ( !resampling ) {
         // No upsampling needed
         out->empty = FALSE;
@@ -835,6 +840,7 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units)
         slot.set(_output, finalout);
     }
 
+    // If we downsampled the input, clean up the downsampled data
     if (in != original_in) nr_pixblock_free(in);
 
     return 0;
index 7546bc1959074725481795be935950be9f9b92b1..da9be1e7c4d620b3a7b796d18fe9ddf4f44be0f0 100644 (file)
@@ -22,6 +22,8 @@ ink_common_sources +=         \
        ui/dialog/color-item.h                  \
        ui/dialog/debug.cpp                     \
        ui/dialog/debug.h                       \
+       ui/dialog/desktop-tracker.cpp           \
+       ui/dialog/desktop-tracker.h             \
        ui/dialog/dialog.cpp                    \
        ui/dialog/dialog.h                      \
        ui/dialog/dialog-manager.cpp            \
diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp
new file mode 100644 (file)
index 0000000..f527f1c
--- /dev/null
@@ -0,0 +1,159 @@
+/**
+ * Glyph selector dialog.
+ */
+
+/* Authors:
+ *   Jon A. Cruz
+ *
+ * Copyright (C) 2010 Jon A. Cruz
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <glib-object.h>
+
+#include "desktop-tracker.h"
+
+#include "inkscape.h"
+#include "desktop.h"
+#include "widgets/desktop-widget.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+DesktopTracker::DesktopTracker() :
+    base(0),
+    desktop(0),
+    widget(0),
+    hierID(0),
+    inkID(0),
+    trackActive(false),
+    desktopChangedSig()
+{
+}
+
+DesktopTracker::~DesktopTracker()
+{
+    disconnect();
+}
+
+void DesktopTracker::connect(GtkWidget *widget)
+{
+    disconnect();
+
+    this->widget = widget;
+
+    // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues:
+    hierID = g_signal_connect( G_OBJECT(widget), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this );
+    inkID = g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(activateDesktopCB), this );
+
+    GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET);
+    if (wdgt && !base) {
+        SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt);
+        if (dtw && dtw->desktop) {
+            setBase(dtw->desktop); // may also set desktop
+        }
+    }
+}
+
+void DesktopTracker::disconnect()
+{
+    if (hierID) {
+        if (widget) {
+            g_signal_handler_disconnect(G_OBJECT(widget), hierID);
+        }
+        hierID = 0;
+    }
+    if (inkID) {
+        if (INKSCAPE) {
+            g_signal_handler_disconnect(G_OBJECT(INKSCAPE), inkID);
+        }
+        inkID = 0;
+    }
+}
+
+void DesktopTracker::setBase(SPDesktop *desktop)
+{
+    if (this->base != desktop) {
+        base = desktop;
+        // Do not override an existing target desktop
+        if (!this->desktop) {
+            setDesktop(desktop);
+        }
+    }
+}
+
+SPDesktop *DesktopTracker::getBase() const
+{
+    return base;
+}
+
+SPDesktop *DesktopTracker::getDesktop() const
+{
+    return desktop;
+}
+
+sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slot<void, SPDesktop*> & slot )
+{
+    return desktopChangedSig.connect(slot);
+}
+
+gboolean DesktopTracker::activateDesktopCB(Inkscape::Application */*inkscape*/, SPDesktop *desktop, DesktopTracker *self )
+{
+    if (self && self->trackActive) {
+        self->setDesktop(desktop);
+    }
+    return FALSE;
+}
+
+bool DesktopTracker::hierarchyChangeCB(GtkWidget * /*widget*/, GtkWidget* /*prev*/, DesktopTracker *self)
+{
+    if (self) {
+        self->handleHierarchyChange();
+    }
+    return false;
+}
+
+void DesktopTracker::handleHierarchyChange()
+{
+    GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET);
+    bool newFlag = (wdgt == 0); // true means not in an SPDesktopWidget, thus floating.
+    if (wdgt && !base) {
+        SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt);
+        if (dtw && dtw->desktop) {
+            setBase(dtw->desktop); // may also set desktop
+        }
+    }
+    if (newFlag != trackActive) {
+        trackActive = newFlag;
+        if (trackActive) {
+            setDesktop(SP_ACTIVE_DESKTOP);
+        } else if (desktop != base) {
+            setDesktop(getBase());
+        }
+    }
+}
+
+void DesktopTracker::setDesktop(SPDesktop *desktop)
+{
+    if (desktop != this->desktop) {
+        this->desktop = desktop;
+        desktopChangedSig.emit(desktop);
+    }
+}
+
+
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h
new file mode 100644 (file)
index 0000000..7a5bc39
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * Glyph selector dialog.
+ */
+
+/* Authors:
+ *   Jon A. Cruz
+ *
+ * Copyright (C) 2010 Jon A. Cruz
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifndef SEEN_DIALOG_DESKTOP_TRACKER
+#define SEEN_DIALOG_DESKTOP_TRACKER
+
+#include <sigc++/connection.h>
+#include <glib/gtypes.h>
+
+typedef struct _GtkWidget GtkWidget;
+class SPDesktop;
+
+namespace Inkscape {
+
+class Application;
+
+namespace UI {
+namespace Dialog {
+
+class DesktopTracker
+{
+public:
+    DesktopTracker();
+    virtual ~DesktopTracker();
+
+    void connect(GtkWidget *widget);
+    void disconnect();
+
+    SPDesktop *getDesktop() const;
+
+    void setBase(SPDesktop *desktop);
+    SPDesktop *getBase() const;
+
+    sigc::connection connectDesktopChanged( const sigc::slot<void, SPDesktop*> & slot );
+
+private:
+    static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, DesktopTracker *self );
+    static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self);
+
+    void handleHierarchyChange();
+    void setDesktop(SPDesktop *desktop);
+
+    SPDesktop *base;
+    SPDesktop *desktop;
+    GtkWidget *widget;
+    gulong hierID;
+    gulong inkID;
+    bool trackActive;
+    sigc::signal<void, SPDesktop*> desktopChangedSig;
+};
+
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+#endif // SEEN_DIALOG_DESKTOP_TRACKER
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 6ee076a940a8710fc181fff3d26481c02b84511a..8c86e1ca46afeb6f025b1d35d11a061b5574ad7b 100644 (file)
@@ -43,11 +43,11 @@ FillAndStroke::FillAndStroke()
       _page_stroke_paint(1, 1, true, true),
       _page_stroke_style(1, 1, true, true),
       _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", UI::Widget::SimpleFilterModifier::BLUR),
-      hierID(0),
-      trackActive(false),
+      deskTrack(),
       targetDesktop(0),
       fillWdgt(0),
-      strokeWdgt(0)
+      strokeWdgt(0),
+      desktopChangeConn()
 {
     Gtk::Box *contents = _getContents();
     contents->set_spacing(0);
@@ -68,59 +68,35 @@ FillAndStroke::FillAndStroke()
 
     _composite_settings.setSubject(&_subject);
 
-    // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues:
-    hierID = g_signal_connect( G_OBJECT(gobj()), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this );
-
-    g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK( activateDesktopCB ), this );
+    // Connect this up last
+    desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &FillAndStroke::setTargetDesktop) );
+    deskTrack.connect(GTK_WIDGET(gobj()));
 }
 
 FillAndStroke::~FillAndStroke()
 {
     _composite_settings.setSubject(NULL);
-    if (hierID) {
-        g_signal_handler_disconnect(G_OBJECT(gobj()), hierID);
-        hierID = 0;
-    }
-}
 
-gboolean FillAndStroke::activateDesktopCB(Inkscape::Application */*inkscape*/, SPDesktop *desktop, FillAndStroke *self )
-{
-    if (self && self->trackActive) {
-        self->setTargetDesktop(desktop);
-    }
-    return FALSE;
-}
-
-bool FillAndStroke::hierarchyChangeCB(GtkWidget *widget, GtkWidget* /*prev*/, FillAndStroke *self)
-{
-    if (self) {
-        GtkWidget *ww = gtk_widget_get_ancestor(widget, SP_TYPE_VIEW_WIDGET);
-        bool newFlag = (ww == 0);
-        if (newFlag != self->trackActive) {
-            self->trackActive = newFlag;
-            if (self->trackActive) {
-                self->setTargetDesktop(SP_ACTIVE_DESKTOP);
-            } else {
-                self->setTargetDesktop(self->getDesktop());
-            }
-        }
-    }
-    return false;
+    desktopChangeConn.disconnect();
+    deskTrack.disconnect();
 }
 
 void FillAndStroke::setDesktop(SPDesktop *desktop)
 {
     Panel::setDesktop(desktop);
-    setTargetDesktop(desktop);
+    deskTrack.setBase(desktop);
 }
 
 void FillAndStroke::setTargetDesktop(SPDesktop *desktop)
 {
-    if (fillWdgt) {
-        sp_fill_style_widget_set_desktop(fillWdgt, desktop);
-    }
-    if (strokeWdgt) {
-        sp_stroke_style_widget_set_desktop(strokeWdgt, desktop);
+    if (targetDesktop != desktop) {
+        targetDesktop = desktop;
+        if (fillWdgt) {
+            sp_fill_style_widget_set_desktop(fillWdgt, desktop);
+        }
+        if (strokeWdgt) {
+            sp_stroke_style_widget_set_desktop(strokeWdgt, desktop);
+        }
     }
 }
 
index a5fe4906a7d7135748b08bc06147bdb99afa7894..2d4e90d734f40d48b0c444ee8bacfd33aa8fa624 100644 (file)
@@ -25,6 +25,7 @@
 #include "ui/widget/panel.h"
 #include "ui/widget/notebook-page.h"
 #include "ui/widget/object-composite-settings.h"
+#include "ui/dialog/desktop-tracker.h"
 
 namespace Inkscape {
 namespace UI {
@@ -40,9 +41,6 @@ public:
 
     virtual void setDesktop(SPDesktop *desktop);
 
-    // temporary work-around until panel dialog itself tracks 'focus' properly.
-    virtual void setTargetDesktop(SPDesktop *desktop);
-
     void selectionChanged(Inkscape::Application *inkscape,
                           Inkscape::Selection *selection);
 
@@ -71,14 +69,13 @@ private:
     FillAndStroke(FillAndStroke const &d);
     FillAndStroke& operator=(FillAndStroke const &d);
 
-    static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, FillAndStroke *self );
-    static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, FillAndStroke *self);
+    void setTargetDesktop(SPDesktop *desktop);
 
-    gulong hierID;
-    bool trackActive;
+    DesktopTracker deskTrack;
     SPDesktop *targetDesktop;
     Gtk::Widget *fillWdgt;
     Gtk::Widget *strokeWdgt;
+    sigc::connection desktopChangeConn;
 };
 
 } // namespace Dialog
index bc96b05754d0173cfe25d261bcade3d191d5a8c1..133cf01ea856e7b4c2471735415e786ee1302607 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace Inkscape {
 namespace UI {
-namespace Dialogs {
+namespace Dialog {
 
 
 GlyphsPanel &GlyphsPanel::getInstance()
@@ -159,8 +159,8 @@ GlyphColumns *GlyphsPanel::getColumns()
 /**
  * Constructor
  */
-GlyphsPanel::GlyphsPanel() :
-    Inkscape::UI::Widget::Panel("", "/dialogs/glyphs", SP_VERB_DIALOG_GLYPHS, "", false),
+GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
+    Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_GLYPHS, "", false),
     store(Gtk::ListStore::create(*getColumns())),
     iconView(0),
     entry(0),
@@ -169,6 +169,8 @@ GlyphsPanel::GlyphsPanel() :
     scriptCombo(0),
 #endif // GLIB_CHECK_VERSION(2,14,0)
     fsel(0),
+    targetDesktop(0),
+    deskTrack(),
     iconActiveConn(),
     iconSelectConn(),
     scriptSelectConn()
@@ -208,7 +210,7 @@ GlyphsPanel::GlyphsPanel() :
             scriptCombo->append_text(it->second);
         }
 
-        scriptCombo->set_active_text(getScriptToName()[G_UNICODE_SCRIPT_INVALID_CODE]);
+        scriptCombo->set_active_text(getScriptToName()[G_UNICODE_SCRIPT_COMMON]); // default to a smaller set
         scriptSelectConn = scriptCombo->signal_changed().connect(sigc::mem_fun(*this, &GlyphsPanel::rebuild));
 
         table->attach( *Gtk::manage(scriptCombo),
@@ -279,6 +281,10 @@ GlyphsPanel::GlyphsPanel() :
     show_all_children();
 
     restorePanelPrefs();
+
+    // Connect this up last
+    desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &GlyphsPanel::setTargetDesktop) );
+    deskTrack.connect(GTK_WIDGET(gobj()));
 }
 
 GlyphsPanel::~GlyphsPanel()
@@ -286,8 +292,22 @@ GlyphsPanel::~GlyphsPanel()
     iconActiveConn.disconnect();
     iconSelectConn.disconnect();
     scriptSelectConn.disconnect();
+    desktopChangeConn.disconnect();
+}
+
+
+void GlyphsPanel::setDesktop(SPDesktop *desktop)
+{
+    Panel::setDesktop(desktop);
+    deskTrack.setBase(desktop);
 }
 
+void GlyphsPanel::setTargetDesktop(SPDesktop *desktop)
+{
+    if (targetDesktop != desktop) {
+        targetDesktop = desktop;
+    }
+}
 
 void GlyphsPanel::glyphActivated(Gtk::TreeModel::Path const & path)
 {
@@ -346,7 +366,7 @@ void GlyphsPanel::rebuild()
         //double  sp_font_selector_get_size (SPFontSelector *fsel);
 
 #if GLIB_CHECK_VERSION(2,14,0)
-        GUnicodeScript script = G_UNICODE_SCRIPT_INVALID_CODE;
+        GUnicodeScript script = G_UNICODE_SCRIPT_COMMON;
         Glib::ustring scriptName = scriptCombo->get_active_text();
         std::map<GUnicodeScript, Glib::ustring> items = getScriptToName();
         for (std::map<GUnicodeScript, Glib::ustring>::iterator it = items.begin(); it != items.end(); ++it) {
@@ -357,6 +377,10 @@ void GlyphsPanel::rebuild()
         }
 #endif // GLIB_CHECK_VERSION(2,14,0)
 
+        // Disconnect the model while we update it. Simple work-around for 5x+ performance boost.
+        Glib::RefPtr<Gtk::ListStore> tmp = Gtk::ListStore::create(*getColumns());
+        iconView->set_model(tmp);
+
         std::vector<gunichar> present;
         for (gunichar ch = 1; ch < 65535; ch++) {
             int glyphId = font->MapUnicodeChar(ch);
@@ -381,6 +405,9 @@ void GlyphsPanel::rebuild()
             (*row)[columns->code] = *it;
             (*row)[columns->name] = tmp;
         }
+
+        // Reconnect the model once it has been updated:
+        iconView->set_model(store);
     }
 }
 
index b4876f3c16366d5bd0f0d0b9d3b7a81f794a0a09..ffd5757b03a2570c6f7b06ccf9df1a4f78b5476f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <gtkmm/treemodel.h>
 #include "ui/widget/panel.h"
+#include "ui/dialog/desktop-tracker.h"
 
 
 namespace Gtk {
@@ -32,7 +33,7 @@ namespace UI {
 
 class PreviewHolder;
 
-namespace Dialogs {
+namespace Dialog {
 
 class GlyphColumns;
 
@@ -43,11 +44,13 @@ class GlyphColumns;
 class GlyphsPanel : public Inkscape::UI::Widget::Panel
 {
 public:
-    GlyphsPanel();
+    GlyphsPanel(gchar const *prefsPath = "/dialogs/glyphs");
     virtual ~GlyphsPanel();
 
     static GlyphsPanel& getInstance();
 
+    virtual void setDesktop(SPDesktop *desktop);
+
 protected:
 
 private:
@@ -62,6 +65,7 @@ private:
 
     void glyphActivated(Gtk::TreeModel::Path const & path);
     void glyphSelectionChanged();
+    void setTargetDesktop(SPDesktop *desktop);
 
 
     Glib::RefPtr<Gtk::ListStore> store;
@@ -72,9 +76,12 @@ private:
     Gtk::ComboBoxText *scriptCombo;
 #endif //GLIB_CHECK_VERSION(2,14,0)
     SPFontSelector *fsel;
+    SPDesktop *targetDesktop;
+    DesktopTracker deskTrack;
     sigc::connection iconActiveConn;
     sigc::connection iconSelectConn;
     sigc::connection scriptSelectConn;
+    sigc::connection desktopChangeConn;
 };