extern bool g_blockEventsOnScroll;
extern wxCursor g_globalCursor;
-static GdkGC *g_eraseGC = NULL;
-
// mouse capture state: the window which has it and if the mouse is currently
// inside it
static wxWindowGTK *g_captureWindow = (wxWindowGTK*) NULL;
{
DEBUG_MAIN_THREAD
- if (g_isIdle)
- wxapp_install_idle_handler();
+ // don't need to install idle handler, its done from "event" signal
// This callback gets called in drawing-idle time under
// GTK 2.0, so we don't need to defer anything to idle
{
DEBUG_MAIN_THREAD
- if (g_isIdle)
- wxapp_install_idle_handler();
+ // don't need to install idle handler, its done from "event" signal
if (!win->m_hasVMT)
return FALSE;
}
}
-
-
-
-
// win is a control: tab can be propagated up
if ( !ret &&
((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
}
- if (ret)
- {
- g_signal_stop_emission_by_name (widget, "key_press_event");
- return TRUE;
- }
-
- return FALSE;
+ return ret;
}
}
{
DEBUG_MAIN_THREAD
- if (g_isIdle)
- wxapp_install_idle_handler();
+ // don't need to install idle handler, its done from "event" signal
if (!win->m_hasVMT)
return FALSE;
return FALSE;
}
- if ( !win->GetEventHandler()->ProcessEvent( event ) )
- return FALSE;
-
- g_signal_stop_emission_by_name (widget, "key_release_event");
- return TRUE;
+ return win->GetEventHandler()->ProcessEvent(event);
}
}
return win;
}
+// ----------------------------------------------------------------------------
+// common event handlers helpers
+// ----------------------------------------------------------------------------
+
+int wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const
+{
+ DEBUG_MAIN_THREAD
+
+ // don't need to install idle handler, its done from "event" signal
+
+ if (!m_hasVMT)
+ return FALSE;
+ if (g_blockEventsOnDrag)
+ return TRUE;
+ if (g_blockEventsOnScroll)
+ return TRUE;
+
+ if (!GTKIsOwnWindow(event->window))
+ return FALSE;
+
+ return -1;
+}
+
+// overloads for all GDK event types we use here: we need to have this as
+// GdkEventXXX can't be implicitly cast to GdkEventAny even if it, in fact,
+// derives from it in the sense that the structs have the same layout
+#define wxDEFINE_COMMON_PROLOGUE_OVERLOAD(T) \
+ static int wxGtkCallbackCommonPrologue(T *event, wxWindowGTK *win) \
+ { \
+ return win->GTKCallbackCommonPrologue((GdkEventAny *)event); \
+ }
+
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventButton)
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventMotion)
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventCrossing)
+
+#undef wxDEFINE_COMMON_PROLOGUE_OVERLOAD
+
+#define wxCOMMON_CALLBACK_PROLOGUE(event, win) \
+ const int rc = wxGtkCallbackCommonPrologue(event, win); \
+ if ( rc != -1 ) \
+ return rc
+
+// send the wxChildFocusEvent and wxFocusEvent, common code of
+// gtk_window_focus_in_callback() and SetFocus()
+static bool DoSendFocusEvents(wxWindow *win)
+{
+ // Notify the parent keeping track of focus for the kbd navigation
+ // purposes that we got it.
+ wxChildFocusEvent eventChildFocus(win);
+ (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
+
+ wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
+ eventFocus.SetEventObject(win);
+
+ return win->GetEventHandler()->ProcessEvent(eventFocus);
+}
+
+// all event handlers must have C linkage as they're called from GTK+ C code
+extern "C"
+{
+
//-----------------------------------------------------------------------------
// "button_press_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_button_press_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
-/*
- wxPrintf( wxT("1) OnButtonPress from ") );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( wxT(".\n") );
-*/
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return TRUE;
- if (g_blockEventsOnScroll) return TRUE;
-
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+ wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
{
gtk_widget_grab_focus( win->m_wxwindow );
-/*
- wxPrintf( wxT("GrabFocus from ") );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( wxT(".\n") );
-*/
}
// GDK sends surplus button down events
if (win->GetEventHandler()->ProcessEvent( event ))
{
- g_signal_stop_emission_by_name (widget, "button_press_event");
return TRUE;
}
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "button_release_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_button_release_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
- if (g_blockEventsOnScroll) return FALSE;
-
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+ wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
wxEventType event_type = wxEVT_NULL;
event.SetEventObject( win );
event.SetId( win->GetId() );
- if (win->GetEventHandler()->ProcessEvent( event ))
- {
- g_signal_stop_emission_by_name (widget, "button_release_event");
- return TRUE;
- }
-
- return FALSE;
-}
+ return win->GetEventHandler()->ProcessEvent(event);
}
//-----------------------------------------------------------------------------
// "motion_notify_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_motion_notify_callback( GtkWidget *widget,
GdkEventMotion *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
- if (g_blockEventsOnScroll) return FALSE;
-
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+ wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
if (gdk_event->is_hint)
{
gdk_event->y = y;
}
-/*
- printf( "OnMotion from " );
- if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
- printf( win->GetClassInfo()->GetClassName() );
- printf( ".\n" );
-*/
-
wxMouseEvent event( wxEVT_MOTION );
InitMouseEvent(win, event, gdk_event);
}
}
- if (win->GetEventHandler()->ProcessEvent( event ))
- {
- g_signal_stop_emission_by_name (widget, "motion_notify_event");
- return TRUE;
- }
-
- return FALSE;
-}
+ return win->GetEventHandler()->ProcessEvent(event);
}
//-----------------------------------------------------------------------------
// "scroll_event", (mouse wheel event)
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
{
DEBUG_MAIN_THREAD
- if (g_isIdle)
- wxapp_install_idle_handler();
+ // don't need to install idle handler, its done from "event" signal
if (gdk_event->direction != GDK_SCROLL_UP &&
gdk_event->direction != GDK_SCROLL_DOWN)
return win->GetEventHandler()->ProcessEvent(event);
}
-}
//-----------------------------------------------------------------------------
// "popup-menu"
//-----------------------------------------------------------------------------
-extern "C" {
+
static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win)
{
- wxContextMenuEvent event(
- wxEVT_CONTEXT_MENU,
- win->GetId(),
- wxPoint(-1, -1));
+ wxContextMenuEvent event(wxEVT_CONTEXT_MENU, win->GetId(), wxPoint(-1, -1));
event.SetEventObject(win);
return win->GetEventHandler()->ProcessEvent(event);
}
-}
//-----------------------------------------------------------------------------
// "focus_in_event"
//-----------------------------------------------------------------------------
-// send the wxChildFocusEvent and wxFocusEvent, common code of
-// gtk_window_focus_in_callback() and SetFocus()
-static bool DoSendFocusEvents(wxWindow *win)
-{
- // Notify the parent keeping track of focus for the kbd navigation
- // purposes that we got it.
- wxChildFocusEvent eventChildFocus(win);
- (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
-
- wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
- eventFocus.SetEventObject(win);
-
- return win->GetEventHandler()->ProcessEvent(eventFocus);
-}
-
-extern "C" {
static gboolean
gtk_window_focus_in_callback( GtkWidget *widget,
GdkEventFocus *WXUNUSED(event),
{
DEBUG_MAIN_THREAD
- if (g_isIdle)
- wxapp_install_idle_handler();
+ // don't need to install idle handler, its done from "event" signal
if (win->m_imData)
gtk_im_context_focus_in(win->m_imData->context);
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "focus_out_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_focus_out_callback( GtkWidget *widget,
GdkEventFocus *gdk_event,
{
DEBUG_MAIN_THREAD
- if (g_isIdle)
- wxapp_install_idle_handler();
+ // don't need to install idle handler, its done from "event" signal
if (win->m_imData)
gtk_im_context_focus_out(win->m_imData->context);
return FALSE;
}
-}
//-----------------------------------------------------------------------------
// "enter_notify_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_enter_callback( GtkWidget *widget,
GdkEventCrossing *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
+ wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
// Event was emitted after a grab
if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE;
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
-
int x = 0;
int y = 0;
GdkModifierType state = (GdkModifierType)0;
}
}
- if (win->GetEventHandler()->ProcessEvent( event ))
- {
- g_signal_stop_emission_by_name (widget, "enter_notify_event");
- return TRUE;
- }
-
- return FALSE;
-}
+ return win->GetEventHandler()->ProcessEvent(event);
}
//-----------------------------------------------------------------------------
// "leave_notify_event"
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_window_leave_callback( GtkWidget *widget,
GdkEventCrossing *gdk_event,
wxWindowGTK *win )
{
- DEBUG_MAIN_THREAD
-
- if (g_isIdle)
- wxapp_install_idle_handler();
-
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
+ wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
// Event was emitted after an ungrab
if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE;
- if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
-
wxMouseEvent event( wxEVT_LEAVE_WINDOW );
event.SetTimestamp( gdk_event->time );
event.SetEventObject( win );
event.m_x = x + pt.x;
event.m_y = y + pt.y;
- if (win->GetEventHandler()->ProcessEvent( event ))
- {
- g_signal_stop_emission_by_name (widget, "leave_notify_event");
- return TRUE;
- }
-
- return FALSE;
-}
+ return win->GetEventHandler()->ProcessEvent(event);
}
//-----------------------------------------------------------------------------
// "value_changed" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static void
gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
{
win->m_blockValueChanged[dir] = false;
}
}
-}
//-----------------------------------------------------------------------------
// "button_press_event" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win)
{
DEBUG_MAIN_THREAD
- if (g_isIdle)
- wxapp_install_idle_handler();
+ // don't need to install idle handler, its done from "event" signal
g_blockEventsOnScroll = true;
win->m_mouseButtonDown = true;
return false;
}
-}
//-----------------------------------------------------------------------------
// "event_after" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static void
gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win)
{
win->GetEventHandler()->ProcessEvent(event);
}
}
-}
//-----------------------------------------------------------------------------
// "button_release_event" from scrollbar
//-----------------------------------------------------------------------------
-extern "C" {
static gboolean
gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* win)
{
return false;
}
-}
-
-// ----------------------------------------------------------------------------
-// this wxWindowBase function is implemented here (in platform-specific file)
-// because it is static and so couldn't be made virtual
-// ----------------------------------------------------------------------------
-
-wxWindow *wxWindowBase::DoFindFocus()
-{
- // the cast is necessary when we compile in wxUniversal mode
- return (wxWindow *)g_focusWindow;
-}
//-----------------------------------------------------------------------------
// "realize" from m_widget
/* We cannot set colours and fonts before the widget has
been realized, so we do this directly after realization. */
-extern "C" {
static void
gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
{
event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event );
}
-}
//-----------------------------------------------------------------------------
// "size_allocate"
//-----------------------------------------------------------------------------
-extern "C" {
static
void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
GtkAllocation *WXUNUSED(alloc),
win->GetEventHandler()->ProcessEvent( event );
}
}
-}
#ifdef HAVE_XIM
#endif
/* Resize XIM window */
-
-extern "C" {
static
void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
GtkAllocation* WXUNUSED_UNLESS_XIM(alloc),
}
#endif // HAVE_XIM
}
-}
//-----------------------------------------------------------------------------
// "realize" from m_wxwindow
/* Initialize XIM support */
-extern "C" {
static void
gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
wxWindowGTK * WXUNUSED_UNLESS_XIM(win) )
}
#endif // HAVE_XIM
}
+
+} // extern "C"
+
+// ----------------------------------------------------------------------------
+// this wxWindowBase function is implemented here (in platform-specific file)
+// because it is static and so couldn't be made virtual
+// ----------------------------------------------------------------------------
+
+wxWindow *wxWindowBase::DoFindFocus()
+{
+ // the cast is necessary when we compile in wxUniversal mode
+ return (wxWindow *)g_focusWindow;
}
//-----------------------------------------------------------------------------
m_hasVMT = false;
m_needParent = true;
m_isBeingDeleted = false;
+
+ m_showOnIdle= false;
m_noExpose = false;
m_nativeSizeEvent = false;
m_resizing = false;
}
+bool wxWindowGTK::GtkShowFromOnIdle()
+{
+ if (IsShown() && m_showOnIdle && !GTK_WIDGET_VISIBLE (m_widget))
+ {
+ GtkAllocation alloc;
+ alloc.x = m_x;
+ alloc.y = m_y;
+ alloc.width = m_width;
+ alloc.height = m_height;
+ gtk_widget_size_allocate( m_widget, &alloc );
+ gtk_widget_show( m_widget );
+ wxShowEvent eventShow(GetId(), true);
+ eventShow.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(eventShow);
+ m_showOnIdle = false;
+ return true;
+ }
+
+ return false;
+}
+
void wxWindowGTK::OnInternalIdle()
{
+ // Check if we have to show window now
+ if (GtkShowFromOnIdle()) return;
+
if ( m_dirtyTabOrder )
{
m_dirtyTabOrder = false;
SetBackgroundStyle(GetBackgroundStyle());
m_needsStyleChange = false;
}
-
- // Update invalidated regions.
- GtkUpdate();
-
+
wxCursor cursor = m_cursor;
if (g_globalCursor.Ok()) cursor = g_globalCursor;
}
if (show)
- gtk_widget_show( m_widget );
+ {
+ if (!m_showOnIdle)
+ {
+ gtk_widget_show( m_widget );
+ wxShowEvent eventShow(GetId(), show);
+ eventShow.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(eventShow);
+ }
+ }
else
+ {
gtk_widget_hide( m_widget );
-
- wxShowEvent eventShow(GetId(), show);
- eventShow.SetEventObject(this);
-
- GetEventHandler()->ProcessEvent(eventShow);
+ wxShowEvent eventShow(GetId(), show);
+ eventShow.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(eventShow);
+ }
return true;
}
g_object_unref (layout);
}
+bool wxWindowGTK::GTKSetDelayedFocusIfNeeded()
+{
+ if ( g_delayedFocus == this )
+ {
+ if ( GTK_WIDGET_REALIZED(m_widget) )
+ {
+ gtk_widget_grab_focus(m_widget);
+ g_delayedFocus = NULL;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
void wxWindowGTK::SetFocus()
{
wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
if (newParent)
{
+ if (GTK_WIDGET_VISIBLE (newParent->m_widget))
+ {
+ m_showOnIdle = true;
+ gtk_widget_hide( m_widget );
+ }
+
/* insert GTK representation */
(*(newParent->m_insertCallback))(newParent, this);
}
if (g_isIdle)
wxapp_install_idle_handler();
- if (cursor == wxNullCursor)
- return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR );
- else
- return wxWindowBase::SetCursor( cursor );
+ return wxWindowBase::SetCursor( cursor.Ok() ? cursor : *wxSTANDARD_CURSOR );
+}
+
+void wxWindowGTK::GTKUpdateCursor()
+{
+ wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor());
+ if ( cursor.Ok() )
+ {
+ wxArrayGdkWindows windowsThis;
+ GdkWindow * const winThis = GTKGetWindow(windowsThis);
+ if ( winThis )
+ {
+ gdk_window_set_cursor(winThis, cursor.GetCursor());
+ }
+ else
+ {
+ const size_t count = windowsThis.size();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ GdkWindow *win = windowsThis[n];
+ if ( !win )
+ {
+ wxFAIL_MSG(_T("NULL window returned by GTKGetWindow()?"));
+ continue;
+ }
+
+ gdk_window_set_cursor(win, cursor.GetCursor());
+ }
+ }
+ }
}
void wxWindowGTK::WarpPointer( int x, int y )
if (m_wxwindow)
{
+ if (!GTK_PIZZA(m_wxwindow)->bin_window) return;
+
GdkRectangle gdk_rect,
*p;
if (rect)
return connect_widget;
}
-bool wxWindowGTK::IsOwnGtkWindow( GdkWindow *window )
+bool wxWindowGTK::GTKIsOwnWindow(GdkWindow *window) const
{
- if (m_wxwindow)
- return (window == GTK_PIZZA(m_wxwindow)->bin_window);
+ wxArrayGdkWindows windowsThis;
+ GdkWindow * const winThis = GTKGetWindow(windowsThis);
- return (window == m_widget->window);
+ return winThis ? window == winThis
+ : windowsThis.Index(window) != wxNOT_FOUND;
+}
+
+GdkWindow *wxWindowGTK::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
+{
+ return m_wxwindow ? GTK_PIZZA(m_wxwindow)->bin_window : m_widget->window;
}
bool wxWindowGTK::SetFont( const wxFont &font )
gtk_grab_remove( (GtkWidget*) window->GetHandle() );
}
-// ----------------------------------------------------------------------------
-// wxWinModule
-// ----------------------------------------------------------------------------
-
-class wxWinModule : public wxModule
-{
-public:
- bool OnInit();
- void OnExit();
-
-private:
- DECLARE_DYNAMIC_CLASS(wxWinModule)
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxWinModule, wxModule)
-
-bool wxWinModule::OnInit()
-{
- // g_eraseGC = gdk_gc_new( gdk_get_default_root_window() );
- // gdk_gc_set_fill( g_eraseGC, GDK_SOLID );
-
- return true;
-}
-
-void wxWinModule::OnExit()
-{
- if (g_eraseGC)
- g_object_unref (g_eraseGC);
-}