#include <hildon-widgets/hildon-window.h>
#endif // wxUSE_LIBHILDON
+#if wxUSE_LIBHILDON2
+ #include <hildon/hildon.h>
+#endif // wxUSE_LIBHILDON2
+
// ----------------------------------------------------------------------------
// data
// ----------------------------------------------------------------------------
wxTopLevelWindow *win )
{
const bool wasIconized = win->IsIconized();
- win->SetIconizeState(false);
if (wasIconized)
{
// Because GetClientSize() returns (0,0) when IsIconized() is true,
eventShow.SetEventObject(win);
win->GetEventHandler()->ProcessEvent(eventShow);
}
+
+#if GTK_CHECK_VERSION(2,6,0)
+ if (!gtk_check_version(2,6,0))
+ {
+ // restore focus-on-map setting in case ShowWithoutActivating() was called
+ gtk_window_set_focus_on_map(GTK_WINDOW(win->m_widget), true);
+ }
+#endif // GTK+ 2.6+
+
return false;
}
}
//-----------------------------------------------------------------------------
-// "unmap_event" from m_widget
+// "window-state-event" from m_widget
//-----------------------------------------------------------------------------
extern "C" {
static gboolean
-gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
- GdkEvent * WXUNUSED(event),
+gtk_frame_window_state_callback( GtkWidget* WXUNUSED(widget),
+ GdkEventWindowState *event,
wxTopLevelWindow *win )
{
- win->SetIconizeState(true);
+ if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED)
+ win->SetIconizeState((event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0);
+
+ // if maximized bit changed and it is now set
+ if (event->changed_mask & event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
+ {
+ wxMaximizeEvent event(win->GetId());
+ event.SetEventObject(win);
+ win->HandleWindowEvent(event);
+ }
+
return false;
}
}
static GdkAtom property = gdk_atom_intern("_NET_FRAME_EXTENTS", false);
if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property)
{
+ wxSize decorSize = win->m_decorSize;
int left, right, top, bottom;
if (wxGetFrameExtents(event->window, &left, &right, &top, &bottom))
- {
- const wxSize decorSize =
- wxSize(left + right, top + bottom);
- win->GTKUpdateDecorSize(decorSize);
- }
+ decorSize.Set(left + right, top + bottom);
+
+ win->GTKUpdateDecorSize(decorSize);
}
return false;
}
m_gdkFunc = 0;
m_grabbed = false;
m_deferShow = true;
+ m_deferShowAllowed = true;
m_updateDecorSize = true;
m_urgency_hint = -2;
// e.g. in wxTaskBarIconAreaGTK
if (m_widget == NULL)
{
-#if wxUSE_LIBHILDON
+#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
// we must create HildonWindow and not a normal GtkWindow as the latter
// doesn't look correctly in Maemo environment and it must also be
// registered with the main program object
m_widget = hildon_window_new();
hildon_program_add_window(wxTheApp->GetHildonProgram(),
HILDON_WINDOW(m_widget));
-#else // !wxUSE_LIBHILDON
+#else // !wxUSE_LIBHILDON || !wxUSE_LIBHILDON2
m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
{
style |= wxFRAME_NO_TASKBAR;
}
}
-#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
+#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON || !wxUSE_LIBHILDON2
g_object_ref(m_widget);
}
{
gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE);
}
+ if (style & wxMAXIMIZE)
+ gtk_window_maximize(GTK_WINDOW(m_widget));
#if 0
if (!name.empty())
g_signal_connect (m_widget, "realize",
G_CALLBACK (gtk_frame_realized_callback), this);
- // map and unmap for iconized state
+ // for some reported size corrections
g_signal_connect (m_widget, "map_event",
G_CALLBACK (gtk_frame_map_callback), this);
- g_signal_connect (m_widget, "unmap_event",
- G_CALLBACK (gtk_frame_unmap_callback), this);
+
+ // for iconized state
+ g_signal_connect (m_widget, "window_state_event",
+ G_CALLBACK (gtk_frame_window_state_callback), this);
+
// for wxMoveEvent
g_signal_connect (m_widget, "configure_event",
wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
{
-#if wxUSE_LIBHILDON
+#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
// it can also be a (standard) dialog
if ( HILDON_IS_WINDOW(m_widget) )
{
hildon_program_remove_window(wxTheApp->GetHildonProgram(),
HILDON_WINDOW(m_widget));
}
-#endif // wxUSE_LIBHILDON
+#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2
if (m_grabbed)
{
- wxFAIL_MSG(_T("Window still grabbed"));
+ wxFAIL_MSG(wxT("Window still grabbed"));
RemoveGrab();
}
// overridden wxWindow methods
// ----------------------------------------------------------------------------
+void wxTopLevelWindowGTK::Refresh( bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect) )
+{
+ wxCHECK_RET( m_widget, wxT("invalid frame") );
+
+ gtk_widget_queue_draw( m_widget );
+
+ if (m_wxwindow && m_wxwindow->window)
+ gdk_window_invalidate_rect( m_wxwindow->window, NULL, TRUE );
+}
+
bool wxTopLevelWindowGTK::Show( bool show )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
bool deferShow = show && !m_isShown && m_deferShow;
if (deferShow)
{
- deferShow = false;
- if (!GTK_WIDGET_REALIZED(m_widget) &&
- g_signal_handler_find(m_widget,
+ deferShow = m_deferShowAllowed && !GTK_WIDGET_REALIZED(m_widget);
+ if (deferShow)
+ {
+ deferShow = g_signal_handler_find(m_widget,
GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET),
- 0, NULL, NULL, this))
+ 0, NULL, NULL, this) != 0;
+ }
+ GdkScreen* screen = NULL;
+ if (deferShow)
{
- if (gdk_x11_screen_supports_net_wm_hint(
- gtk_widget_get_screen(m_widget),
- gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false)))
- {
- deferShow = true;
- }
- else
- {
- // Don't allow changes to m_decorSize, it breaks saving/restoring
- // window size with GetSize()/SetSize() because it makes window
- // bigger between each restore and save.
- m_updateDecorSize = false;
- }
+ screen = gtk_widget_get_screen(m_widget);
+ GdkAtom atom = gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false);
+ deferShow = gdk_x11_screen_supports_net_wm_hint(screen, atom) != 0;
+ // If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes
+ // to m_decorSize, it breaks saving/restoring window size with
+ // GetSize()/SetSize() because it makes window bigger between each
+ // restore and save.
+ m_updateDecorSize = deferShow;
}
+ if (deferShow)
+ {
+ // Fluxbox support for _NET_REQUEST_FRAME_EXTENTS is broken
+ const char* name = gdk_x11_screen_get_window_manager_name(screen);
+ deferShow = strcmp(name, "Fluxbox") != 0;
+ m_updateDecorSize = deferShow;
+ }
+
m_deferShow = deferShow;
}
if (deferShow)
HandleWindowEvent(event);
}
- bool change = wxTopLevelWindowBase::Show(show);
+ bool change = base_type::Show(show);
if (change && !show)
{
return change;
}
+void wxTopLevelWindowGTK::ShowWithoutActivating()
+{
+ if (!m_isShown)
+ {
+#if GTK_CHECK_VERSION(2,6,0)
+ if (!gtk_check_version(2,6,0))
+ gtk_window_set_focus_on_map(GTK_WINDOW(m_widget), false);
+#endif // GTK+ 2.6+
+
+ Show(true);
+ }
+}
+
void wxTopLevelWindowGTK::Raise()
{
gtk_window_present( GTK_WINDOW( m_widget ) );
size -= m_decorSize;
if (size.x < 0) size.x = 0;
if (size.y < 0) size.y = 0;
+#if wxUSE_LIBHILDON2
+ if (width) {
+ if (size.x == 720)
+ *width = 696;
+ else
+ *width = size.x;
+ }
+ if (height) {
+ if (size.y == 420)
+ *height = 396;
+ else if (size.y == 270)
+ *height = 246;
+ else
+ *height = size.y;
+ }
+#else // wxUSE_LIBHILDON2
if (width) *width = size.x;
if (height) *height = size.y;
+#endif // wxUSE_LIBHILDON2 /!wxUSE_LIBHILDON2
}
void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
{
wxCHECK_RET( m_widget, wxT("invalid frame") );
+ m_deferShowAllowed = true;
+
// deal with the position first
int old_x = m_x;
int old_y = m_y;
void wxTopLevelWindowGTK::DoSetClientSize(int width, int height)
{
- if (m_deferShow && !m_isShown)
- // Since client size is being explicitly set, don't change it later
- m_deferShow = false;
- wxTopLevelWindowBase::DoSetClientSize(width, height);
+ base_type::DoSetClientSize(width, height);
+
+ // Since client size is being explicitly set, don't change it later
+ // Has to be done after calling base because it calls SetSize,
+ // which sets this true
+ m_deferShowAllowed = false;
}
void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
int maxW, int maxH,
int incW, int incH )
{
- wxTopLevelWindowBase::DoSetSizeHints( minW, minH, maxW, maxH, incW, incH );
+ base_type::DoSetSizeHints(minW, minH, maxW, maxH, incW, incH);
const wxSize minSize = GetMinSize();
const wxSize maxSize = GetMaxSize();
void wxTopLevelWindowGTK::OnInternalIdle()
{
- wxWindow::OnInternalIdle();
+ wxTopLevelWindowBase::OnInternalIdle();
// Synthetize activate events.
if ( g_sendActivateEvent != -1 )
{
wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
- wxTopLevelWindowBase::SetIcons( icons );
+ base_type::SetIcons(icons);
// Setting icons before window is realized can cause a GTK assertion if
// another TLW is realized before this one, and it has this one as it's
bool wxTopLevelWindowGTK::IsMaximized() const
{
- if(!m_widget->window)
- return false;
-
- return gdk_window_get_state(m_widget->window) & GDK_WINDOW_STATE_MAXIMIZED;
+ return m_widget->window &&
+ (gdk_window_get_state(m_widget->window) & GDK_WINDOW_STATE_MAXIMIZED);
}
void wxTopLevelWindowGTK::Restore()
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."));
if ( GTK_WIDGET_REALIZED(m_widget) )
{
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 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.
+ // YieldFor(wxEVT_CATEGORY_UI) ensures the processing of it (hopefully it
+ // won't have side effects) - MR
+ wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI);
if(m_urgency_hint >= 0)
g_source_remove(m_urgency_hint);
bool wxTopLevelWindowGTK::CanSetTransparent()
{
// allow to override automatic detection as it's far from perfect
- static const wxChar *SYSOPT_TRANSPARENT = wxT("gtk.tlw.can-set-transparent");
+ const wxString SYSOPT_TRANSPARENT = "gtk.tlw.can-set-transparent";
if ( wxSystemOptions::HasOption(SYSOPT_TRANSPARENT) )
{
return wxSystemOptions::GetOptionInt(SYSOPT_TRANSPARENT) != 0;