X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fgtkmm2ext%2Fwindow_proxy.cc;h=9ba0e320de6e27461aaf3ebd541011af1d42b4be;hb=58db958839db7c052b95aae86ce9eb6f66ce9854;hp=e18596dd9e9f6a8c1e3f7c534bbd2a6329574c92;hpb=e46b5183199dbe00c63f79332a2e04e516cb646f;p=ardour.git diff --git a/libs/gtkmm2ext/window_proxy.cc b/libs/gtkmm2ext/window_proxy.cc index e18596dd9e..9ba0e320de 100644 --- a/libs/gtkmm2ext/window_proxy.cc +++ b/libs/gtkmm2ext/window_proxy.cc @@ -20,13 +20,12 @@ #include #include -#include "pbd/convert.h" #include "pbd/xml++.h" #include "gtkmm2ext/window_proxy.h" #include "gtkmm2ext/visibility_tracker.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace Gtk; using namespace Gtkmm2ext; @@ -39,8 +38,9 @@ WindowProxy::WindowProxy (const std::string& name) , _x_off (-1) , _y_off (-1) , _width (-1) - , _height (-1) + , _height (-1) , vistracker (0) + , _state_mask (StateMask (Position|Size)) { } @@ -52,8 +52,9 @@ WindowProxy::WindowProxy (const std::string& name, const std::string& menu_name) , _x_off (-1) , _y_off (-1) , _width (-1) - , _height (-1) + , _height (-1) , vistracker (0) + , _state_mask (StateMask (Position|Size)) { } @@ -65,8 +66,9 @@ WindowProxy::WindowProxy (const std::string& name, const std::string& menu_name, , _x_off (-1) , _y_off (-1) , _width (-1) - , _height (-1) + , _height (-1) , vistracker (0) + , _state_mask (StateMask (Position|Size)) { set_state (node, 0); } @@ -81,12 +83,14 @@ int WindowProxy::set_state (const XMLNode& node, int /* version */) { XMLNodeList children = node.children (); - + XMLNode const * child; XMLNodeList::const_iterator i = children.begin (); while (i != children.end()) { - XMLProperty* prop = (*i)->property (X_("name")); - if ((*i)->name() == X_("Window") && prop && prop->value() == _name) { + child = *i; + std::string name; + if (child->name () == X_("Window") && child->get_property (X_("name"), name) && + name == _name) { break; } @@ -95,26 +99,13 @@ WindowProxy::set_state (const XMLNode& node, int /* version */) if (i != children.end()) { - XMLProperty* prop; - - std::cerr << " PB setting state\n"; - - if ((prop = (*i)->property (X_("visible"))) != 0) { - _visible = PBD::string_is_affirmative (prop->value ()); - } + child = *i; - if ((prop = (*i)->property (X_("x-off"))) != 0) { - _x_off = atoi (prop->value()); - } - if ((prop = (*i)->property (X_("y-off"))) != 0) { - _y_off = atoi (prop->value()); - } - if ((prop = (*i)->property (X_("x-size"))) != 0) { - _width = atoi (prop->value()); - } - if ((prop = (*i)->property (X_("y-size"))) != 0) { - _height = atoi (prop->value()); - } + child->get_property (X_("visible"), _visible); + child->get_property (X_("x-off"), _x_off); + child->get_property (X_("y-off"), _y_off); + child->get_property (X_("x-size"), _width); + child->get_property (X_("y-size"), _height); } if (_window) { @@ -131,16 +122,17 @@ WindowProxy::set_action (Glib::RefPtr act) } std::string -WindowProxy::action_name() const +WindowProxy::action_name() const { return string_compose (X_("toggle-%1"), _name); } void -WindowProxy::toggle() +WindowProxy::toggle() { if (!_window) { (void) get (true); + setup (); assert (_window); /* XXX this is a hack - the window object should really ensure its components are all visible. sigh. @@ -148,12 +140,17 @@ WindowProxy::toggle() _window->show_all(); /* we'd like to just call this and nothing else */ _window->present (); - } else { if (_window->is_mapped()) { save_pos_and_size(); } - vistracker->cycle_visibility (); + + if (vistracker) { + vistracker->cycle_visibility (); + } else { + _window->present (); + } + if (_window->is_mapped()) { if (_width != -1 && _height != -1) { _window->set_default_size (_width, _height); @@ -175,12 +172,11 @@ XMLNode& WindowProxy::get_state () { XMLNode* node = new XMLNode (xml_node_name()); - char buf[32]; - node->add_property (X_("name"), _name); + node->set_property (X_("name"), _name); if (_window && vistracker) { - + /* we have a window, so use current state */ _visible = vistracker->partially_visible (); @@ -188,15 +184,29 @@ WindowProxy::get_state () _window->get_size (_width, _height); } - node->add_property (X_("visible"), _visible? X_("yes") : X_("no")); - snprintf (buf, sizeof (buf), "%d", _x_off); - node->add_property (X_("x-off"), buf); - snprintf (buf, sizeof (buf), "%d", _y_off); - node->add_property (X_("y-off"), buf); - snprintf (buf, sizeof (buf), "%d", _width); - node->add_property (X_("x-size"), buf); - snprintf (buf, sizeof (buf), "%d", _height); - node->add_property (X_("y-size"), buf); + int x, y, w, h; + + if (_state_mask & Position) { + x = _x_off; + y = _y_off; + } else { + x = -1; + y = -1; + } + + if (_state_mask & Size) { + w = _width; + h = _height; + } else { + w = -1; + h = -1; + } + + node->set_property (X_("visible"), _visible); + node->set_property (X_("x-off"), x); + node->set_property (X_("y-off"), y); + node->set_property (X_("x-size"), w); + node->set_property (X_("y-size"), h); return *node; } @@ -206,6 +216,10 @@ WindowProxy::drop_window () { if (_window) { _window->hide (); + delete_connection.disconnect (); + configure_connection.disconnect (); + map_connection.disconnect (); + unmap_connection.disconnect (); delete _window; _window = 0; delete vistracker; @@ -226,12 +240,68 @@ WindowProxy::setup () { assert (_window); - vistracker = new Gtkmm2ext::VisibilityTracker (*_window); - _window->signal_delete_event().connect (sigc::mem_fun (*this, &WindowProxy::delete_event_handler)); + assert (_window); + + delete_connection = _window->signal_delete_event().connect (sigc::mem_fun (*this, &WindowProxy::delete_event_handler)); + configure_connection = _window->signal_configure_event().connect (sigc::mem_fun (*this, &WindowProxy::configure_handler), false); + map_connection = _window->signal_map().connect (sigc::mem_fun (*this, &WindowProxy::map_handler), false); + unmap_connection = _window->signal_unmap().connect (sigc::mem_fun (*this, &WindowProxy::unmap_handler), false); set_pos_and_size (); } - + +void +WindowProxy::map_handler () +{ + vistracker = new Gtkmm2ext::VisibilityTracker (*_window); + /* emit our own signal */ + signal_map (); +} + +void +WindowProxy::unmap_handler () +{ + /* emit out own signal */ + signal_unmap (); +} + +bool +WindowProxy::configure_handler (GdkEventConfigure* ev) +{ + /* stupidly, the geometry data in the event isn't the same as we get + from the window geometry APIs.so we have to actively interrogate + them to get the new information. + + the difference is generally down to window manager framing. + */ + if (!visible() || !_window->is_mapped()) { + return false; + } + save_pos_and_size (); + return false; +} + + +bool +WindowProxy::visible() const +{ + if (vistracker) { + /* update with current state */ + _visible = vistracker->partially_visible(); + } + return _visible; +} + +bool +WindowProxy::fully_visible () const +{ + if (!vistracker) { + /* no vistracker .. no window .. cannot be fully visible */ + return false; + } + return vistracker->fully_visible(); +} + void WindowProxy::show () { @@ -281,7 +351,12 @@ WindowProxy::hide () bool WindowProxy::delete_event_handler (GdkEventAny* /*ev*/) { - hide(); + if (_action) { + _action->activate (); + } else { + hide(); + } + return true; } @@ -301,13 +376,34 @@ WindowProxy::set_pos_and_size () return; } - if (_width != -1 || _height != -1 || _x_off != -1 || _y_off != -1) { + if ((_state_mask & Position) && (_width != -1 || _height != -1 || _x_off != -1 || _y_off != -1)) { /* cancel any mouse-based positioning */ _window->set_position (Gtk::WIN_POS_NONE); } - if (_width != -1 && _height != -1) { - _window->set_default_size (_width, _height); + if ((_state_mask & Size) && _width != -1 && _height != -1) { + _window->resize (_width, _height); + } + + if ((_state_mask & Position) && _x_off != -1 && _y_off != -1) { + _window->move (_x_off, _y_off); + } +} + +void +WindowProxy::set_pos () +{ + if (!_window) { + return; + } + + if (!(_state_mask & Position)) { + return; + } + + if (_width != -1 || _height != -1 || _x_off != -1 || _y_off != -1) { + /* cancel any mouse-based positioning */ + _window->set_position (Gtk::WIN_POS_NONE); } if (_x_off != -1 && _y_off != -1) { @@ -315,3 +411,8 @@ WindowProxy::set_pos_and_size () } } +void +WindowProxy::set_state_mask (StateMask sm) +{ + _state_mask = sm; +}