/////////////////////////////////////////////////////////////////////////////
-// Name: toplevel.cpp
+// Name: src/gtk1/toplevel.cpp
// Purpose:
// Author: Robert Roebling
// Id: $Id$
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
// ============================================================================
// declarations
// ============================================================================
// headers
// ----------------------------------------------------------------------------
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
- #pragma implementation "toplevel.h"
-#endif
-
-// For compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
-
#ifdef __VMS
#define XIconifyWindow XICONIFYWINDOW
#endif
-#include "wx/defs.h"
-
#include "wx/toplevel.h"
-#include "wx/log.h"
-#include "wx/dialog.h"
-#include "wx/control.h"
-#include "wx/app.h"
-#include "wx/dcclient.h"
-#include "wx/gtk/private.h"
-#include "wx/timer.h"
-#include "wx/settings.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/log.h"
+ #include "wx/app.h"
+ #include "wx/dcclient.h"
+ #include "wx/dialog.h"
+ #include "wx/timer.h"
+ #include "wx/settings.h"
+ #include "wx/control.h"
+#endif
+
+#include "wx/gtk1/private.h"
#include "wx/evtloop.h"
#include <glib.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
-#include "wx/gtk/win_gtk.h"
+#include "wx/gtk1/win_gtk.h"
#include "wx/unix/utilsx11.h"
// data
// ----------------------------------------------------------------------------
-extern wxList wxPendingDelete;
-
extern int g_openDialogs;
extern wxWindowGTK *g_delayedFocus;
// the frame that is currently active (i.e. its child has focus). It is
// used to generate wxActivateEvents
-static wxTopLevelWindowGTK *g_activeFrame = (wxTopLevelWindowGTK*) NULL;
-static wxTopLevelWindowGTK *g_lastActiveFrame = (wxTopLevelWindowGTK*) NULL;
+static wxTopLevelWindowGTK *g_activeFrame = NULL;
+static wxTopLevelWindowGTK *g_lastActiveFrame = NULL;
// if we detect that the app has got/lost the focus, we set this variable to
// either TRUE or FALSE and an activate event will be sent during the next
// send any activate events at all
static int g_sendActivateEvent = -1;
+//-----------------------------------------------------------------------------
+// RequestUserAttention related functions
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static void wxgtk_window_set_urgency_hint (GtkWindow *win,
+ gboolean setting)
+{
+ wxASSERT_MSG( GTK_WIDGET_REALIZED(win), wxT("wxgtk_window_set_urgency_hint: GdkWindow not realized") );
+ GdkWindow *window = GTK_WIDGET(win)->window;
+ XWMHints *wm_hints;
+
+ wm_hints = XGetWMHints(GDK_WINDOW_XDISPLAY(window), GDK_WINDOW_XWINDOW(window));
+
+ if (!wm_hints)
+ wm_hints = XAllocWMHints();
+
+ if (setting)
+ wm_hints->flags |= XUrgencyHint;
+ else
+ wm_hints->flags &= ~XUrgencyHint;
+
+ XSetWMHints(GDK_WINDOW_XDISPLAY(window), GDK_WINDOW_XWINDOW(window), wm_hints);
+ XFree(wm_hints);
+}
+
+static gint gtk_frame_urgency_timer_callback( wxTopLevelWindowGTK *win )
+{
+ wxgtk_window_set_urgency_hint(GTK_WINDOW( win->m_widget ), FALSE);
+
+ win->m_urgency_hint = -2;
+ return FALSE;
+}
+}
+
//-----------------------------------------------------------------------------
// "focus_in_event"
//-----------------------------------------------------------------------------
// wxPrintf( wxT("active: %s\n"), win->GetTitle().c_str() );
+ // MR: wxRequestUserAttention related block
+ switch( win->m_urgency_hint )
+ {
+ default:
+ gtk_timeout_remove( win->m_urgency_hint );
+ // no break, fallthrough to remove hint too
+ case -1:
+ wxgtk_window_set_urgency_hint(GTK_WINDOW( widget ), FALSE);
+
+ win->m_urgency_hint = -2;
+ break;
+
+ case -2: break;
+ }
+
wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame);
wxActivateEvent event(wxEVT_ACTIVATE, true, g_activeFrame->GetId());
event.SetEventObject(g_activeFrame);
- g_activeFrame->GetEventHandler()->ProcessEvent(event);
+ g_activeFrame->HandleWindowEvent(event);
return FALSE;
}
//-----------------------------------------------------------------------------
extern "C" {
-static gint gtk_frame_focus_out_callback( GtkWidget *widget,
+static gint gtk_frame_focus_out_callback( GtkWidget *WXUNUSED(widget),
GdkEventFocus *WXUNUSED(gdk_event),
- wxTopLevelWindowGTK *win )
+ wxTopLevelWindowGTK *WXUNUSED(win) )
{
if (g_isIdle)
wxapp_install_idle_handler();
wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), g_activeFrame);
wxActivateEvent event(wxEVT_ACTIVATE, false, g_activeFrame->GetId());
event.SetEventObject(g_activeFrame);
- g_activeFrame->GetEventHandler()->ProcessEvent(event);
+ g_activeFrame->HandleWindowEvent(event);
g_activeFrame = NULL;
}
wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
mevent.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( mevent );
+ win->HandleWindowEvent( mevent );
return FALSE;
}
// reset the icon
wxIconBundle iconsOld = win->GetIcons();
- if ( iconsOld.GetIcon(-1).Ok() )
+ if ( !iconsOld.IsEmpty() )
{
win->SetIcon( wxNullIcon );
win->SetIcons( iconsOld );
GdkEvent * WXUNUSED(event),
wxTopLevelWindow *win )
{
- win->SetIconizeState(TRUE);
+ win->SetIconizeState(true);
}
}
// "draw" of m_client
//-----------------------------------------------------------------------------
-#ifndef __WXGTK20__
-
extern "C" {
static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
{
}
}
-#endif // GTK+ 1.x
-
// ----------------------------------------------------------------------------
// wxTopLevelWindowGTK itself
// ----------------------------------------------------------------------------
m_sizeSet = false;
m_miniEdge = 0;
m_miniTitle = 0;
- m_mainWidget = (GtkWidget*) NULL;
+ m_mainWidget = NULL;
m_insertInClientArea = true;
m_isIconized = false;
m_fsIsShowing = false;
m_themeEnabled = true;
m_gdkDecor = m_gdkFunc = 0;
m_grabbed = false;
+
+ m_urgency_hint = -2;
}
bool wxTopLevelWindowGTK::Create( wxWindow *parent,
{
if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
{
-#ifdef __WXGTK20__
- m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- // Tell WM that this is a dialog window and make it center
- // on parent by default (this is what GtkDialog ctor does):
- gtk_window_set_type_hint(GTK_WINDOW(m_widget),
- GDK_WINDOW_TYPE_HINT_DIALOG);
- gtk_window_set_position(GTK_WINDOW(m_widget),
- GTK_WIN_POS_CENTER_ON_PARENT);
-#else
m_widget = gtk_window_new(GTK_WINDOW_DIALOG);
-#endif
}
else
{
GTK_WINDOW(topParent->m_widget) );
}
-#if GTK_CHECK_VERSION(2,2,0)
- if (!gtk_check_version(2,2,0))
- {
- if (style & wxFRAME_NO_TASKBAR)
- {
- gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE);
- }
- }
-#endif
-
-#if GTK_CHECK_VERSION(2,4,0)
- if (!gtk_check_version(2,4,0))
- {
- if (style & wxSTAY_ON_TOP)
- {
- gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
- }
- }
-#endif
-
if (!name.empty())
gtk_window_set_wmclass( GTK_WINDOW(m_widget), wxGTK_CONV( name ), wxGTK_CONV( name ) );
// For m_mainWidget themes
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
-#ifndef __WXGTK20__
gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
-#endif
}
// m_wxwindow only represents the client area without toolbar and menubar
gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
- // the only way to get the window size is to connect to this event
- gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
- GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
-
// map and unmap for iconized state
gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
{
if (m_grabbed)
{
- wxASSERT_MSG( FALSE, _T("Window still grabbed"));
+ wxASSERT_MSG( false, wxT("Window still grabbed"));
RemoveGrab();
}
- m_isBeingDeleted = true;
+ SendDestroyEvent();
// it may also be GtkScrolledWindow in the case of an MDI child
if (GTK_IS_WINDOW(m_widget))
gtk_window_fullscreen( GTK_WINDOW( m_widget ) );
else
gtk_window_unfullscreen( GTK_WINDOW( m_widget ) );
-
- return true;
}
else
#endif // GTK+ >= 2.2.0
(WXWindow)GDK_WINDOW_XWINDOW(window),
show, &m_fsSaveFrame, method);
}
- else
+ else // hide
{
if (method != wxX11_FS_WMSPEC)
{
}
}
+ // documented behaviour is to show the window if it's still hidden when
+ // showing it full screen
+ if ( show && !IsShown() )
+ Show();
+
return true;
}
void wxTopLevelWindowGTK::Raise()
{
-#ifdef __WXGTK20__
- gtk_window_present( GTK_WINDOW( m_widget ) );
-#else
wxWindow::Raise();
-#endif
}
void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
: maxHeight ;
gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
- (GtkWidget*) NULL,
+ NULL,
&geom,
(GdkWindowHints) flag );
// send size event to frame
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
event.SetEventObject( this );
- GetEventHandler()->ProcessEvent( event );
+ HandleWindowEvent( event );
m_resizing = false;
}
if ( g_delayedFocus &&
wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this )
{
- wxLogTrace(_T("focus"),
- _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
+ wxLogTrace(wxT("focus"),
+ wxT("Setting focus from wxTLW::OnIdle() to %s(%s)"),
g_delayedFocus->GetClassInfo()->GetClassName(),
g_delayedFocus->GetLabel().c_str());
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
+ if ( title == m_title )
+ return;
+
m_title = title;
- gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
-}
-void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon )
-{
- SetIcons( wxIconBundle( icon ) );
+ gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
}
void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons )
wxTopLevelWindowBase::SetIcons( icons );
-#ifdef __WXGTK20__
- GList *list = NULL;
- size_t max = icons.m_icons.GetCount();
-
- for (size_t i = 0; i < max; i++)
- {
- if (icons.m_icons[i].Ok())
- {
- list = g_list_prepend(list, icons.m_icons[i].GetPixbuf());
- }
- }
- gtk_window_set_icon_list(GTK_WINDOW(m_widget), list);
- g_list_free(list);
+ if ( icons.IsEmpty() )
+ return;
-#else // !__WXGTK20__
GdkWindow* window = m_widget->window;
if (!window)
return;
if (icon.Ok())
{
wxMask *mask = icon.GetMask();
- GdkBitmap *bm = (GdkBitmap *) NULL;
+ GdkBitmap *bm = NULL;
if (mask) bm = mask->GetBitmap();
- gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
+ gdk_window_set_icon( m_widget->window, NULL, icon.GetPixmap(), bm );
}
wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ),
(WXWindow)GDK_WINDOW_XWINDOW( window ), icons );
-#endif // !__WXGTK20__
}
// ----------------------------------------------------------------------------
// frame state: maximized/iconized/normal
// ----------------------------------------------------------------------------
-void wxTopLevelWindowGTK::Maximize(bool maximize)
+void wxTopLevelWindowGTK::Maximize(bool WXUNUSED(maximize))
{
-#ifdef __WXGTK20__
- if (maximize)
- gtk_window_maximize( GTK_WINDOW( m_widget ) );
- else
- gtk_window_unmaximize( GTK_WINDOW( m_widget ) );
-#else
- wxFAIL_MSG( _T("not implemented") );
-#endif
+ wxFAIL_MSG( wxT("not implemented") );
}
bool wxTopLevelWindowGTK::IsMaximized() const
{
-#ifdef __WXGTK20__
- if(!m_widget->window)
- return false;
-
- return gdk_window_get_state(m_widget->window) & GDK_WINDOW_STATE_MAXIMIZED;
-#else
- // wxFAIL_MSG( _T("not implemented") );
+ // wxFAIL_MSG( wxT("not implemented") );
// This is an approximation
return false;
-#endif
}
void wxTopLevelWindowGTK::Restore()
{
-#ifdef __WXGTK20__
- // "Present" seems similar enough to "restore"
- gtk_window_present( GTK_WINDOW( m_widget ) );
-#else
- wxFAIL_MSG( _T("not implemented") );
-#endif
+ wxFAIL_MSG( wxT("not implemented") );
}
void wxTopLevelWindowGTK::Iconize( bool iconize )
{
-#ifdef __WXGTK20__
- if (iconize)
- gtk_window_iconify( GTK_WINDOW( m_widget ) );
- else
- gtk_window_deiconify( GTK_WINDOW( m_widget ) );
-#else
if (iconize)
{
GdkWindow *window = m_widget->window;
// you should do it later, for example from OnCreate() handler
- wxCHECK_RET( window, _T("frame not created yet - can't iconize") );
+ wxCHECK_RET( window, wxT("frame not created yet - can't iconize") );
XIconifyWindow( GDK_WINDOW_XDISPLAY( window ),
GDK_WINDOW_XWINDOW( window ),
DefaultScreen( GDK_DISPLAY() ) );
}
-#endif
}
bool wxTopLevelWindowGTK::IsIconized() const
}
else
{
-#ifdef __WXGTK20__
- gdk_window_shape_combine_region(window, region.GetRegion(), 0, 0);
-#else
wxBitmap bmp = region.ConvertToBitmap();
bmp.SetMask(new wxMask(bmp, *wxBLACK));
GdkBitmap* mask = bmp.GetMask()->GetBitmap();
gdk_window_shape_combine_mask(window, mask, 0, 0);
-#endif
return true;
}
}
bool wxTopLevelWindowGTK::SetShape(const wxRegion& region)
{
wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false,
- _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
+ wxT("Shaped windows must be created with the wxFRAME_SHAPED style."));
GdkWindow *window = NULL;
if (m_wxwindow)
{
return (this == (wxTopLevelWindowGTK*)g_activeFrame);
}
+
+void wxTopLevelWindowGTK::RequestUserAttention(int flags)
+{
+ bool new_hint_value = false;
+
+ // FIXME: This is a workaround to focus handling problem
+ // If RequestUserAttention is called for example right after a wxSleep, OnInternalIdle hasn't
+ // yet been processed, and the internal focus system is not up to date yet.
+ // wxYieldIfNeeded ensures the processing of it, but can have unwanted side effects - MR
+ ::wxYieldIfNeeded();
+
+ if(m_urgency_hint >= 0)
+ gtk_timeout_remove(m_urgency_hint);
+
+ m_urgency_hint = -2;
+
+ if( GTK_WIDGET_REALIZED(m_widget) && !IsActive() )
+ {
+ new_hint_value = true;
+
+ if (flags & wxUSER_ATTENTION_INFO)
+ {
+ m_urgency_hint = gtk_timeout_add(5000, (GtkFunction)gtk_frame_urgency_timer_callback, this);
+ } else {
+ m_urgency_hint = -1;
+ }
+ }
+
+ wxgtk_window_set_urgency_hint(GTK_WINDOW( m_widget ), new_hint_value);
+}
+
+void wxTopLevelWindowGTK::SetWindowStyleFlag( long style )
+{
+ // Process wxWindow styles. This also updates the internal variable
+ // Therefore m_windowStyle bits carry now the _new_ style values
+ wxWindow::SetWindowStyleFlag(style);
+}