/////////////////////////////////////////////////////////////////////////////
-// 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
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
- #pragma implementation "toplevel.h"
-#endif
-
#ifdef __VMS
#define XIconifyWindow XICONIFYWINDOW
#endif
-#include "wx/defs.h"
+#include "wx/toplevel.h"
-#include "wx/dialog.h"
-#include "wx/control.h"
-#include "wx/app.h"
-#include "wx/dcclient.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/gdk.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;
+
+// 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
+// OnIdle() call and it is reset to -1: this value means that we shouldn't
+// 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"
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static gint gtk_frame_focus_in_callback( GtkWidget *widget,
+ GdkEvent *WXUNUSED(event),
+ wxTopLevelWindowGTK *win )
+{
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+
+ switch ( g_sendActivateEvent )
+ {
+ case -1:
+ // we've got focus from outside, synthetize wxActivateEvent
+ g_sendActivateEvent = 1;
+ break;
+
+ case 0:
+ // another our window just lost focus, it was already ours before
+ // - don't send any wxActivateEvent
+ g_sendActivateEvent = -1;
+ break;
+ }
+
+ g_activeFrame = win;
+ g_lastActiveFrame = g_activeFrame;
+
+ // 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);
+
+ return FALSE;
+}
+}
+
+//-----------------------------------------------------------------------------
+// "focus_out_event"
+//-----------------------------------------------------------------------------
+
+extern "C" {
+static gint gtk_frame_focus_out_callback( GtkWidget *widget,
+ GdkEventFocus *WXUNUSED(gdk_event),
+ wxTopLevelWindowGTK *win )
+{
+ if (g_isIdle)
+ wxapp_install_idle_handler();
+
+ // if the focus goes out of our app alltogether, OnIdle() will send
+ // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset
+ // g_sendActivateEvent to -1
+ g_sendActivateEvent = 0;
+
+ // wxASSERT_MSG( (g_activeFrame == win), wxT("TLW deactivatd although it wasn't active") );
+
+ // wxPrintf( wxT("inactive: %s\n"), win->GetTitle().c_str() );
-extern int g_openDialogs;
-extern wxWindowGTK *g_delayedFocus;
+ if (g_activeFrame)
+ {
+ 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 = NULL;
+ }
+
+ return FALSE;
+}
+}
//-----------------------------------------------------------------------------
// "focus" from m_window
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
{
if (g_isIdle)
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
return TRUE;
}
+}
//-----------------------------------------------------------------------------
// "size_allocate"
//-----------------------------------------------------------------------------
+extern "C" {
static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxTopLevelWindowGTK *win )
{
if (g_isIdle)
win->m_width = alloc->width;
win->m_height = alloc->height;
- win->m_queuedFullRedraw = TRUE;
win->GtkUpdateSize();
}
}
+}
//-----------------------------------------------------------------------------
// "delete_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win )
{
if (g_isIdle)
return TRUE;
}
+}
//-----------------------------------------------------------------------------
// "configure_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint
gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxTopLevelWindowGTK *win )
{
if (!win->m_hasVMT || !win->IsShown())
return FALSE;
+
int x = 0;
int y = 0;
gdk_window_get_root_origin( win->m_widget->window, &x, &y );
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "realize" from m_widget
// we cannot MWM hints and icons before the widget has been realized,
// so we do this directly after realization
+extern "C" {
static void
gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
wxTopLevelWindowGTK *win )
// reset the icon
wxIconBundle iconsOld = win->GetIcons();
- if ( iconsOld.GetIcon(-1).Ok() )
+ if ( !iconsOld.IsEmpty() )
{
win->SetIcon( wxNullIcon );
win->SetIcons( iconsOld );
}
}
+}
//-----------------------------------------------------------------------------
// "map_event" from m_widget
//-----------------------------------------------------------------------------
+extern "C" {
static void
gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
GdkEvent * WXUNUSED(event),
wxTopLevelWindow *win )
{
- win->SetIconizeState(FALSE);
+ win->SetIconizeState(false);
+}
}
//-----------------------------------------------------------------------------
// "unmap_event" from m_widget
//-----------------------------------------------------------------------------
+extern "C" {
static void
gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
GdkEvent * WXUNUSED(event),
wxTopLevelWindow *win )
{
- win->SetIconizeState(TRUE);
+ win->SetIconizeState(true);
+}
}
//-----------------------------------------------------------------------------
// "expose_event" of m_client
//-----------------------------------------------------------------------------
+extern "C" {
static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
{
GtkPizza *pizza = GTK_PIZZA(widget);
(char *)"base",
0, 0, -1, -1);
- return TRUE;
+ return FALSE;
+}
}
//-----------------------------------------------------------------------------
// "draw" of m_client
//-----------------------------------------------------------------------------
-#ifndef __WXGTK20__
-
+extern "C" {
static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
{
GtkPizza *pizza = GTK_PIZZA(widget);
(char *)"base",
0, 0, -1, -1);
}
-
-#endif // GTK+ 1.x
+}
// ----------------------------------------------------------------------------
// wxTopLevelWindowGTK itself
/* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
* C++ has no virtual methods in a constructor. We have to emulate a
- * virtual function here as wxWindows requires different ways to insert
+ * virtual function here as wxWidgets requires different ways to insert
* a child in container classes. */
static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow* child )
void wxTopLevelWindowGTK::Init()
{
- m_sizeSet = FALSE;
+ m_sizeSet = false;
m_miniEdge = 0;
m_miniTitle = 0;
m_mainWidget = (GtkWidget*) NULL;
- m_insertInClientArea = TRUE;
- m_isIconized = FALSE;
- m_fsIsShowing = FALSE;
- m_themeEnabled = TRUE;
+ m_insertInClientArea = true;
+ m_isIconized = false;
+ m_fsIsShowing = false;
+ m_themeEnabled = true;
m_gdkDecor = m_gdkFunc = 0;
- m_grabbed = FALSE;
+ m_grabbed = false;
+
+ m_urgency_hint = -2;
}
bool wxTopLevelWindowGTK::Create( wxWindow *parent,
// always create a frame of some reasonable, even if arbitrary, size (at
// least for MSW compatibility)
wxSize size = sizeOrig;
- if ( size.x == -1 || size.y == -1 )
- {
- wxSize sizeDpy = wxGetDisplaySize();
- if ( size.x == -1 )
- size.x = sizeDpy.x / 3;
- if ( size.y == -1 )
- size.y = sizeDpy.y / 5;
- }
+ size.x = WidthDefault(size.x);
+ size.y = HeightDefault(size.y);
wxTopLevelWindows.Append( this );
- m_needParent = FALSE;
+ m_needParent = false;
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
{
wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
- return FALSE;
+ return false;
}
m_title = title;
m_insertCallback = (wxInsertChildFunction) wxInsertChildInTopLevelWindow;
- GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
-
- if (style & wxFRAME_TOOL_WINDOW)
- win_type = GTK_WINDOW_POPUP;
-
- if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
+ // NB: m_widget may be !=NULL if it was created by derived class' Create,
+ // e.g. in wxTaskBarIconAreaGTK
+ if (m_widget == NULL)
{
- // there is no more GTK_WINDOW_DIALOG in 2.0
-#ifdef __WXGTK20__
- win_type = GTK_WINDOW_TOPLEVEL;
-#else
- win_type = GTK_WINDOW_DIALOG;
+ if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
+ {
+ m_widget = gtk_window_new(GTK_WINDOW_DIALOG);
+ }
+ else
+ {
+ m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+#if GTK_CHECK_VERSION(2,1,0)
+ if (!gtk_check_version(2,1,0))
+ {
+ if (style & wxFRAME_TOOL_WINDOW)
+ {
+ gtk_window_set_type_hint(GTK_WINDOW(m_widget),
+ GDK_WINDOW_TYPE_HINT_UTILITY);
+
+ // On some WMs, like KDE, a TOOL_WINDOW will still show
+ // on the taskbar, but on Gnome a TOOL_WINDOW will not.
+ // For consistency between WMs and with Windows, we
+ // should set the NO_TASKBAR flag which will apply
+ // the set_skip_taskbar_hint if it is available,
+ // ensuring no taskbar entry will appear.
+ style |= wxFRAME_NO_TASKBAR;
+ }
+ }
#endif
+ }
}
- m_widget = gtk_window_new( win_type );
-
- if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)) &&
- (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG))
+ wxWindow *topParent = wxGetTopLevelParent(m_parent);
+ if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) &&
+ (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) ||
+ (style & wxFRAME_FLOAT_ON_PARENT)))
{
- gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
+ gtk_window_set_transient_for( GTK_WINDOW(m_widget),
+ GTK_WINDOW(topParent->m_widget) );
}
- if (!name.IsEmpty())
- gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
+ if (!name.empty())
+ gtk_window_set_wmclass( GTK_WINDOW(m_widget), wxGTK_CONV( name ), wxGTK_CONV( name ) );
- gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
+ gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
- // for m_mainWidget themes
- gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
+ if (m_miniEdge == 0) // wxMiniFrame has its own version.
+ {
+ // 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_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
m_wxwindow = gtk_pizza_new();
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 );
gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
+ // activation
+ gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
+ GTK_SIGNAL_FUNC(gtk_frame_focus_in_callback), (gpointer)this );
+ gtk_signal_connect( GTK_OBJECT(m_widget), "focus_out_event",
+ GTK_SIGNAL_FUNC(gtk_frame_focus_out_callback), (gpointer)this );
+
// decorations
if ((m_miniEdge > 0) || (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
{
// All this is for Motif Window Manager "hints" and is supposed to be
// recognized by other WMs as well.
if ((style & wxCAPTION) != 0)
+ {
m_gdkDecor |= GDK_DECOR_TITLE;
- if ((style & wxSYSTEM_MENU) != 0)
+ }
+ if ((style & wxCLOSE_BOX) != 0)
{
m_gdkFunc |= GDK_FUNC_CLOSE;
+ }
+ if ((style & wxSYSTEM_MENU) != 0)
+ {
m_gdkDecor |= GDK_DECOR_MENU;
}
if ((style & wxMINIMIZE_BOX) != 0)
}
}
- return TRUE;
+ return true;
}
wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
{
if (m_grabbed)
{
- wxASSERT_MSG( FALSE, "Window still grabbed");
+ wxASSERT_MSG( false, _T("Window still grabbed"));
RemoveGrab();
}
-
- m_isBeingDeleted = TRUE;
+
+ m_isBeingDeleted = true;
// it may also be GtkScrolledWindow in the case of an MDI child
if (GTK_IS_WINDOW(m_widget))
gtk_window_set_focus( GTK_WINDOW(m_widget), NULL );
}
- wxTopLevelWindows.DeleteObject( this );
-
- if (wxTheApp->GetTopWindow() == this)
- wxTheApp->SetTopWindow( (wxWindow*) NULL );
-
- if ((wxTopLevelWindows.Number() == 0) &&
- (wxTheApp->GetExitOnFrameDelete()))
- {
- wxTheApp->ExitMainLoop();
- }
+ if (g_activeFrame == this)
+ g_activeFrame = NULL;
+ if (g_lastActiveFrame == this)
+ g_lastActiveFrame = NULL;
}
-// X11 ICCCM values for window layers
-#define WIN_LAYER_NORMAL 4
-#define WIN_LAYER_ABOVE_DOCK 10
-
-// X11 window manager property name
-#define XA_WIN_LAYER "_WIN_LAYER"
-
-// X11 window manager property name atom
-static Atom gs_XA_WIN_LAYER = 0;
-
-
-static void wx_win_hints_set_layer(GtkWidget *window, int layer)
-{
- XEvent xev;
- GdkWindowPrivate *priv;
- gint prev_error;
-
- prev_error = gdk_error_warnings;
- gdk_error_warnings = 0;
- priv = (GdkWindowPrivate*)(GTK_WIDGET(window)->window);
-
- if (GTK_WIDGET_MAPPED(window))
- {
- xev.type = ClientMessage;
- xev.xclient.type = ClientMessage;
- xev.xclient.window = priv->xwindow;
- xev.xclient.message_type = gs_XA_WIN_LAYER;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = (long)layer;
- xev.xclient.data.l[1] = gdk_time_get();
-
- XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False,
- SubstructureNotifyMask, (XEvent*) &xev);
- }
- else
- {
- long data[1];
-
- data[0] = layer;
- XChangeProperty(GDK_DISPLAY(), priv->xwindow, gs_XA_WIN_LAYER,
- XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data,
- 1);
- }
- gdk_error_warnings = prev_error;
-}
bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
{
- if (show == m_fsIsShowing) return FALSE; // return what?
-
- if (gs_XA_WIN_LAYER == 0)
- {
- // Initialose X11 Atom only once
- gs_XA_WIN_LAYER = XInternAtom( GDK_DISPLAY(), XA_WIN_LAYER, False );
- }
+ if (show == m_fsIsShowing)
+ return false; // return what?
m_fsIsShowing = show;
- if (show)
- {
- m_fsSaveGdkFunc = m_gdkFunc;
- m_fsSaveGdkDecor = m_gdkDecor;
- m_fsSaveFlag = style;
- GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
- GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
+ wxX11FullScreenMethod method =
+ wxGetFullScreenMethodX11((WXDisplay*)GDK_DISPLAY(),
+ (WXWindow)GDK_ROOT_WINDOW());
- int screen_width,screen_height;
- wxDisplaySize( &screen_width, &screen_height );
-
- gint client_x, client_y, root_x, root_y;
- gint width, height;
-
- gdk_window_get_origin (m_widget->window, &root_x, &root_y);
- gdk_window_get_geometry (m_widget->window, &client_x, &client_y,
- &width, &height, NULL);
-
- wx_win_hints_set_layer( m_widget, WIN_LAYER_ABOVE_DOCK );
-
- gdk_window_move_resize (m_widget->window, -client_x, -client_y,
- screen_width + 1, screen_height + 1);
+#if GTK_CHECK_VERSION(2,2,0)
+ // NB: gtk_window_fullscreen() uses freedesktop.org's WMspec extensions
+ // to switch to fullscreen, which is not always available. We must
+ // check if WM supports the spec and use legacy methods if it
+ // doesn't.
+ if ( (method == wxX11_FS_WMSPEC) && !gtk_check_version(2,2,0) )
+ {
+ if (show)
+ gtk_window_fullscreen( GTK_WINDOW( m_widget ) );
+ else
+ gtk_window_unfullscreen( GTK_WINDOW( m_widget ) );
}
else
+#endif // GTK+ >= 2.2.0
{
- wx_win_hints_set_layer( m_widget, WIN_LAYER_NORMAL );
-
- SetSize( m_fsSaveFrame.x, m_fsSaveFrame.y, m_fsSaveFrame.width, m_fsSaveFrame.height );
+ GdkWindow *window = m_widget->window;
+
+ if (show)
+ {
+ m_fsSaveFlag = style;
+ GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
+ GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
+
+ int screen_width,screen_height;
+ wxDisplaySize( &screen_width, &screen_height );
+
+ gint client_x, client_y, root_x, root_y;
+ gint width, height;
+
+ if (method != wxX11_FS_WMSPEC)
+ {
+ // don't do it always, Metacity hates it
+ m_fsSaveGdkFunc = m_gdkFunc;
+ m_fsSaveGdkDecor = m_gdkDecor;
+ m_gdkFunc = m_gdkDecor = 0;
+ gdk_window_set_decorations(window, (GdkWMDecoration)0);
+ gdk_window_set_functions(window, (GdkWMFunction)0);
+ }
+
+ gdk_window_get_origin (m_widget->window, &root_x, &root_y);
+ gdk_window_get_geometry (m_widget->window, &client_x, &client_y,
+ &width, &height, NULL);
+
+ gdk_window_move_resize (m_widget->window, -client_x, -client_y,
+ screen_width + 1, screen_height + 1);
+
+ wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
+ (WXWindow)GDK_ROOT_WINDOW(),
+ (WXWindow)GDK_WINDOW_XWINDOW(window),
+ show, &m_fsSaveFrame, method);
+ }
+ else // hide
+ {
+ if (method != wxX11_FS_WMSPEC)
+ {
+ // don't do it always, Metacity hates it
+ m_gdkFunc = m_fsSaveGdkFunc;
+ m_gdkDecor = m_fsSaveGdkDecor;
+ gdk_window_set_decorations(window, (GdkWMDecoration)m_gdkDecor);
+ gdk_window_set_functions(window, (GdkWMFunction)m_gdkFunc);
+ }
+
+ wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(),
+ (WXWindow)GDK_ROOT_WINDOW(),
+ (WXWindow)GDK_WINDOW_XWINDOW(window),
+ show, &m_fsSaveFrame, method);
+
+ SetSize(m_fsSaveFrame.x, m_fsSaveFrame.y,
+ m_fsSaveFrame.width, m_fsSaveFrame.height);
+ }
}
- return TRUE;
+ // documented behaviour is to show the window if it's still hidden when
+ // showing it full screen
+ if ( show && !IsShown() )
+ Show();
+
+ return true;
}
// ----------------------------------------------------------------------------
GtkOnSize( m_x, m_y, m_width, m_height );
}
+ if (show)
+ gtk_widget_set_uposition( m_widget, m_x, m_y );
+
return wxWindow::Show( show );
}
+void wxTopLevelWindowGTK::Raise()
+{
+ wxWindow::Raise();
+}
+
void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
{
wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
// avoid recursions
if (m_resizing)
return;
- m_resizing = TRUE;
+ m_resizing = true;
int old_x = m_x;
int old_y = m_y;
maxWidth = GetMaxWidth(),
maxHeight = GetMaxHeight();
+#ifdef __WXGPE__
+ // GPE's window manager doesn't like size hints
+ // at all, esp. when the user has to use the
+ // virtual keyboard.
+ minWidth = -1;
+ minHeight = -1;
+ maxWidth = -1;
+ maxHeight = -1;
+#endif
+
if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
/* we set the size in GtkOnSize, i.e. mostly the actual resizing is
done either directly before the frame is shown or in idle time
so that different calls to SetSize() don't lead to flicker. */
- m_sizeSet = FALSE;
+ m_sizeSet = false;
}
- m_resizing = FALSE;
+ m_resizing = false;
}
void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
// avoid recursions
if (m_resizing) return;
- m_resizing = TRUE;
+ m_resizing = true;
if ( m_wxwindow == NULL ) return;
maxWidth = GetMaxWidth(),
maxHeight = GetMaxHeight();
+#ifdef __WXGPE__
+ // GPE's window manager doesn't like size hints
+ // at all, esp. when the user has to use the
+ // virtual keyboard.
+ minWidth = -1;
+ minHeight = -1;
+ maxWidth = -1;
+ maxHeight = -1;
+#endif
+
if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
// Gtk-WARNING **: gtk_widget_size_allocate():
// attempt to allocate widget with width 65535 and height 600
// but I don't have time to track them all now..
- //
+ //
// Really we need to encapulate all this height/width business and
// stop any old method from ripping at the members directly and
// scattering -1's without regard for who might resolve them later.
// is no need to set the size or position of m_wxwindow.
}
- m_sizeSet = TRUE;
+ m_sizeSet = true;
// send size event to frame
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
event.SetEventObject( this );
GetEventHandler()->ProcessEvent( event );
- m_resizing = FALSE;
+ m_resizing = false;
}
void wxTopLevelWindowGTK::OnInternalIdle()
if ( g_delayedFocus &&
wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this )
{
+ wxLogTrace(_T("focus"),
+ _T("Setting focus from wxTLW::OnIdle() to %s(%s)"),
+ g_delayedFocus->GetClassInfo()->GetClassName(),
+ g_delayedFocus->GetLabel().c_str());
+
g_delayedFocus->SetFocus();
g_delayedFocus = NULL;
}
}
wxWindow::OnInternalIdle();
+
+ // Synthetize activate events.
+ if ( g_sendActivateEvent != -1 )
+ {
+ bool activate = g_sendActivateEvent != 0;
+
+ // if (!activate) wxPrintf( wxT("de") );
+ // wxPrintf( wxT("activate\n") );
+
+ // do it only once
+ g_sendActivateEvent = -1;
+
+ wxTheApp->SetActive(activate, (wxWindow *)g_lastActiveFrame);
+ }
}
// ----------------------------------------------------------------------------
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
- m_title = title;
- gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
-}
-
-void wxTopLevelWindowGTK::DoSetIcon( const wxIcon &icon )
-{
- if ( !icon.Ok() )
+ if ( title == m_title )
return;
- if (!m_widget->window)
- return;
-
- wxMask *mask = icon.GetMask();
- GdkBitmap *bm = (GdkBitmap *) NULL;
- if (mask) bm = mask->GetBitmap();
-
- gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
-}
+ m_title = 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 )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
- GdkWindow* window = m_widget->window;
wxTopLevelWindowBase::SetIcons( icons );
- DoSetIcon( icons.GetIcon( -1 ) );
- if ( window )
+ if ( icons.IsEmpty() )
+ return;
+
+ GdkWindow* window = m_widget->window;
+ if (!window)
+ return;
+
+ wxIcon icon = icons.GetIcon(-1);
+ if (icon.Ok())
{
- wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ),
- (WXWindow)GDK_WINDOW_XWINDOW( window ), icons );
+ wxMask *mask = icon.GetMask();
+ GdkBitmap *bm = (GdkBitmap *) NULL;
+ if (mask) bm = mask->GetBitmap();
+
+ gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
}
+
+ wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ),
+ (WXWindow)GDK_WINDOW_XWINDOW( window ), icons );
}
// ----------------------------------------------------------------------------
// frame state: maximized/iconized/normal
// ----------------------------------------------------------------------------
-void wxTopLevelWindowGTK::Maximize(bool WXUNUSED(maximize))
+void wxTopLevelWindowGTK::Maximize(bool maximize)
{
wxFAIL_MSG( _T("not implemented") );
}
// wxFAIL_MSG( _T("not implemented") );
// This is an approximation
- return FALSE;
+ return false;
}
void wxTopLevelWindowGTK::Restore()
{
if (!m_grabbed)
{
- m_grabbed = TRUE;
+ m_grabbed = true;
gtk_grab_add( m_widget );
- gtk_main();
+ wxEventLoop().Run();
gtk_grab_remove( m_widget );
}
}
if (m_grabbed)
{
gtk_main_quit();
- m_grabbed = FALSE;
+ m_grabbed = false;
+ }
+}
+
+
+// helper
+static bool do_shape_combine_region(GdkWindow* window, const wxRegion& region)
+{
+ if (window)
+ {
+ if (region.IsEmpty())
+ {
+ gdk_window_shape_combine_mask(window, NULL, 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);
+ return true;
+ }
}
+ return false;
}
-// vi:sts=4:sw=4:et
+
+bool wxTopLevelWindowGTK::SetShape(const wxRegion& region)
+{
+ wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), false,
+ _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
+
+ GdkWindow *window = NULL;
+ if (m_wxwindow)
+ {
+ window = GTK_PIZZA(m_wxwindow)->bin_window;
+ do_shape_combine_region(window, region);
+ }
+ window = m_widget->window;
+ return do_shape_combine_region(window, region);
+}
+
+bool wxTopLevelWindowGTK::IsActive()
+{
+ 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);
+}