ardour/libs/gtkmm2/gtk/src/window.ccg
Paul Davis 449aab3c46 rollback to 3428, before the mysterious removal of libs/* at 3431/3432
git-svn-id: svn://localhost/ardour2/branches/3.0@3435 d708f5d6-7413-0410-9779-e7cbd77b26cf
2008-06-02 21:41:35 +00:00

206 lines
6.3 KiB
C++

// -*- c++ -*-
/* $Id: window.ccg,v 1.5 2006/05/10 20:59:28 murrayc Exp $ */
/*
*
* Copyright 1998-2002 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gtkmm/accelgroup.h>
#include <gdkmm/cursor.h>
#include <gtk/gtkwindow.h>
namespace Gtk
{
Glib::RefPtr<AccelGroup> Window::get_accel_group()
{
//There doesn't seem to be any gtk_window_get_accel_group().
//I think that you're supposed to remember what you added yourself.
//And that's what we do here.
if(!accel_group_)
{
accel_group_ = AccelGroup::create();
add_accel_group(accel_group_);
}
return accel_group_;
}
bool Window::is_toplevel() const
{
return gobj()->type == GTK_WINDOW_TOPLEVEL;
}
bool Window::is_popup() const
{
return gobj()->type == GTK_WINDOW_POPUP;
}
void Window::raise()
{
get_window()->raise();
}
void Window::set_manage()
{
g_warning("gtkmm: Attempt to call Gtk::manage() on a Gtk::Window, but a Gtk::Window has no parent container to manage its lifetime.\n");
}
void Window::destroy_()
{
//Called from destructors.
//overridden so that the correct _destroy_c_instance() ends up being called by the destructor.
//GTKMM_LIFECYCLE
#ifdef GLIBMM_DEBUG_REFCOUNTING
g_warning("Gtk::Window::destroy_(): gobject_: %10X\n", gobject_);
if(gobject_)
g_warning(" gtypename: %s\n", G_OBJECT_TYPE_NAME(gobject_));
#endif
if ( !cpp_destruction_in_progress_ ) //see comment below.
{
//Prevent destroy_notify_() from running as a possible side-effect of gtk_object_destroy.
//We can't predict whether destroy_notify_() will really be run, so we'll disconnect the C++ instance here.
cpp_destruction_in_progress_ = true;
//destroy the C instance:
_destroy_c_instance();
}
//The C++ destructor will be reached later. This function was called by a destructor.
}
void Window::_destroy_c_instance()
{
//We override this,
//because though top-level windows can only be destroyed with gtk_widget_destroy, according to Owen Taylor. murrayc.
#ifdef GLIBMM_DEBUG_REFCOUNTING
g_warning("Gtk::Window::_destroy_c_instance() gobject_=%10X\n", gobject_);
#endif
cpp_destruction_in_progress_ = true;
// remove our hook.
GtkObject* object = (GtkObject*)gobj();
if (object)
{
disconnect_cpp_wrapper();
//If we are killing the C++ instance before the C instance, then this might lead to strange behaviour.
//If this is a problem, then you'll have to use a managed() object, which will die only upon GTK+'s request.
//We can't do anything with the gobject_ if it's already been disposed.
//This prevents us from unref-ing it again, or destroying it again after GTK+ has told us that it has been disposed.
if (!gobject_disposed_)
{
//Windows can not be unrefed. They are "self-owning".
gtk_object_destroy(object);
}
//Glib::Object::~Object() will not g_object_unref() it too. because gobject_ is now 0.
}
}
void Window_Class::dispose_vfunc_callback(GObject* self)
{
//Avoid disposal of Windows on delete_event (window close) signal.
#ifdef GLIBMM_DEBUG_REFCOUNTING
g_warning("Window_Class::dispose_vfunc_callback(): gobject_: %p\n", (void*)self);
#endif
Widget *const obj = dynamic_cast<Widget*>(
Glib::ObjectBase::_get_current_wrapper(self));
// This function might be invoked recursively because we're triggering
// several signal emissions, particularly signal_hide(). Therefore we
// have to test for cpp_destruction_in_progress_ at this point.
if(obj && !obj->_cpp_destruction_is_in_progress()) //When it should really be destroyed, we zero gobj_.
{
GtkWidget* const pWidget = obj->gobj();
g_return_if_fail(pWidget == GTK_WIDGET(self));
// Abort dispose if the widget isn't managed, in order to prevent
// the nasty self-destroying behaviour of GTK+. This applies to:
//
// - GtkWindow, if it received "delete_event"
// - GtkDialog, which destroys on "response" by default
#ifdef GLIBMM_DEBUG_REFCOUNTING
g_warning("Window_Class::dispose_vfunc_callback(): before gtk_widget_hide().");
#endif
// Now hide the widget. The C++ object must _not_ be accessed anymore
// after this call, because a signal_hide() handler might delete it.
gtk_widget_hide(pWidget);
#ifdef GLIBMM_DEBUG_REFCOUNTING
g_warning("Window_Class::dispose_vfunc_callback(): after gtk_widget_hide().");
#endif
// GTKMM_LIFECYCLE
return; // Prevent calling of normal C dispose vfunc (see below)
}
else
{
#ifdef GLIBMM_DEBUG_REFCOUNTING
//g_warning("Window_Class::dispose_vfunc_callback(): unreferenced: before gtk_widget_hide().");
#endif
// Always hide widgets on gtk_object_destroy(), regardless of whether
// the widget is managed or not. This is done for consistency so that
// connecting to signal_hide() is guaranteed to work.
//gtk_widget_hide(pWidget);
#ifdef GLIBMM_DEBUG_REFCOUNTING
//g_warning("Window_Class::dispose_vfunc_callback(): unreferenced: after gtk_widget_hide().");
#endif
GObjectClass *const base = static_cast<GObjectClass*>(
g_type_class_peek_parent(G_OBJECT_GET_CLASS(self)));
#ifdef GLIBMM_DEBUG_REFCOUNTING
g_warning("Window_Class::dispose_vfunc_callback(): before calling base->dispose.");
#endif
if(base->dispose)
(*base->dispose)(self);
#ifdef GLIBMM_DEBUG_REFCOUNTING
g_warning("Window_Class::dispose_vfunc_callback(): after calling base->dispose.");
#endif
}
}
void Window::unset_focus()
{
gtk_window_set_focus(gobj(), 0 /* See GTK+ docs */);
}
void Window::unset_default()
{
gtk_window_set_default(gobj(), 0 /* See GTK+ docs */);
}
} // namespace Gtk