// SPDX-License-Identifier: GPL-2.0-or-later /* Authors: * Jon A. Cruz * * Copyright (C) 2010 Jon A. Cruz * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #include "widgets/desktop-widget.h" #include "desktop-tracker.h" #include "inkscape.h" #include "desktop.h" namespace Inkscape { namespace UI { namespace Dialog { DesktopTracker::DesktopTracker() : base(nullptr), desktop(nullptr), widget(nullptr), hierID(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 = INKSCAPE.signal_activate_desktop.connect( sigc::bind( sigc::ptr_fun(&DesktopTracker::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.connected()) { inkID.disconnect(); } } 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 & slot ) { return desktopChangedSig.connect(slot); } void DesktopTracker::activateDesktopCB(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 == nullptr); // 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:fileencoding=utf-8:textwidth=99 :