#include "wx/thread.h"
#endif
-#include <math.h>
+#include "wx/math.h"
#include <ctype.h>
#include "wx/gtk/private.h"
static wxWindowGTK *g_captureWindow = (wxWindowGTK*) NULL;
static bool g_captureWindowHasMouse = FALSE;
-/* extern */ wxWindowGTK *g_focusWindow = (wxWindowGTK*) NULL;
+wxWindowGTK *g_focusWindow = (wxWindowGTK*) NULL;
// the last window which had the focus - this is normally never NULL (except
// if we never had focus at all) as even when g_focusWindow is NULL it still
// keeps its previous value
-static wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL;
-
-// the frame that is currently active (i.e. its child has focus). It is
-// used to generate wxActivateEvents
-static wxWindowGTK *g_activeFrame = (wxWindowGTK*) NULL;
-static bool g_activeFrameLostFocus = FALSE;
+wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL;
// If a window get the focus set but has not been realized
// yet, defer setting the focus to idle time.
wxWindowGTK *g_delayedFocus = (wxWindowGTK*) 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;
-
// hack: we need something to pass to gtk_menu_popup, so we store the time of
// the last click here
static guint32 gs_timeLastClick = 0;
gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
event.SetTimestamp( gdk_event->time );
+ event.SetId(win->GetId());
event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0;
event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0;
event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0;
event.m_scanCode = gdk_event->keyval;
event.m_rawCode = (wxUint32) gdk_event->keyval;
event.m_rawFlags = 0;
+#if wxUSE_UNICODE
+ event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval);
+#endif
event.m_x = x;
event.m_y = y;
event.SetEventObject( win );
key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */);
if ( !key_code )
{
- if ( gdk_event->length == 1 )
- {
- key_code = (unsigned char)gdk_event->string[0];
- }
- else if ( wxIsAsciiKeysym(keysym) )
+ if ( wxIsAsciiKeysym(keysym) )
{
// ASCII key
key_code = (unsigned char)keysym;
}
+ // gdk_event->string is actually deprecated
+ else if ( gdk_event->length == 1 )
+ {
+ key_code = (unsigned char)gdk_event->string[0];
+ }
}
if ( key_code )
// a chance to correct this
win->FixUpMouseEvent(widget, event.m_x, event.m_y);
- if ( event_type == wxEVT_RIGHT_DOWN )
- {
- // generate a "context menu" event: this is similar to right mouse
- // click under many GUIs except that it is generated differently
- // (right up under MSW, ctrl-click under Mac, right down here) and
- //
- // (a) it's a command event and so is propagated to the parent
- // (b) under MSW it can be generated from kbd too
- // (c) it uses screen coords (because of (a))
- wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
- win->GetId(),
- win->ClientToScreen(event.GetPosition()));
- (void)win->GetEventHandler()->ProcessEvent(evtCtx);
- }
-
// find the correct window to send the event too: it may be a different one
// from the one which got it at GTK+ level because some control don't have
// their own X window and thus cannot get any events.
return TRUE;
}
+ if (event_type == wxEVT_RIGHT_DOWN)
+ {
+ // generate a "context menu" event: this is similar to right mouse
+ // click under many GUIs except that it is generated differently
+ // (right up under MSW, ctrl-click under Mac, right down here) and
+ //
+ // (a) it's a command event and so is propagated to the parent
+ // (b) under some ports it can be generated from kbd too
+ // (c) it uses screen coords (because of (a))
+ wxContextMenuEvent evtCtx(
+ wxEVT_CONTEXT_MENU,
+ win->GetId(),
+ win->ClientToScreen(event.GetPosition()));
+ evtCtx.SetEventObject(win);
+ return win->GetEventHandler()->ProcessEvent(evtCtx);
+ }
+
return FALSE;
}
return FALSE;
}
-#endif
+
+//-----------------------------------------------------------------------------
+// "popup-menu"
+//-----------------------------------------------------------------------------
+static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win)
+{
+ wxContextMenuEvent event(
+ wxEVT_CONTEXT_MENU,
+ win->GetId(),
+ wxPoint(-1, -1));
+ event.SetEventObject(win);
+ return win->GetEventHandler()->ProcessEvent(event);
+}
+#endif // __WXGTK20__
//-----------------------------------------------------------------------------
// "focus_in_event"
wxWindow *win )
{
DEBUG_MAIN_THREAD
-
+
if (g_isIdle)
wxapp_install_idle_handler();
gtk_im_context_focus_in(win->m_imData->context);
#endif
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
-
- 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_focusWindowLast =
g_focusWindow = win;
}
#endif // wxUSE_CARET
- g_activeFrameLostFocus = FALSE;
-
- wxWindowGTK *active = wxGetTopLevelParent(win);
- if ( active != g_activeFrame )
- {
- if ( g_activeFrame )
- {
- wxLogTrace(wxT("activate"), wxT("Deactivating frame %p (from focus_in)"), g_activeFrame);
- wxActivateEvent event(wxEVT_ACTIVATE, FALSE, g_activeFrame->GetId());
- event.SetEventObject(g_activeFrame);
- g_activeFrame->GetEventHandler()->ProcessEvent(event);
- }
-
- wxLogTrace(wxT("activate"), wxT("Activating frame %p (from focus_in)"), active);
- g_activeFrame = active;
- wxActivateEvent event(wxEVT_ACTIVATE, TRUE, g_activeFrame->GetId());
- event.SetEventObject(g_activeFrame);
- g_activeFrame->GetEventHandler()->ProcessEvent(event);
-
- // Don't send focus events in addition to activate
- // if (win == g_activeFrame)
- // return TRUE;
- }
-
// does the window itself think that it has the focus?
if ( !win->m_hasFocus )
{
// not yet, notify it
win->m_hasFocus = TRUE;
-
+
if ( DoSendFocusEvents(win) )
{
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
gtk_im_context_focus_out(win->m_imData->context);
#endif
- if (!win->m_hasVMT) return FALSE;
- if (g_blockEventsOnDrag) return FALSE;
-
wxLogTrace( TRACE_FOCUS,
_T("%s: focus out"), win->GetName().c_str() );
- if ( !g_activeFrameLostFocus && g_activeFrame )
- {
- // VZ: commenting this out because it does happen (although not easy
- // to reproduce, I only see it when using wxMiniFrame and not
- // always) and makes using Mahogany quite annoying
-#if 0
- wxASSERT_MSG( wxGetTopLevelParent(win) == g_activeFrame,
- wxT("unfocusing window that hasn't gained focus properly") );
-#endif // 0
-
- g_activeFrameLostFocus = TRUE;
- }
-
- // 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;
wxWindowGTK *winFocus = wxFindFocusedChild(win);
if ( winFocus )
wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
event.SetEventObject( win );
- if (win->GetEventHandler()->ProcessEvent( event ))
- {
- gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
- return TRUE;
- }
+ // even if we did process the event in wx code, still let GTK itself
+ // process it too as otherwise bad things happen, especially in GTK2
+ // where the text control simply aborts the program if it doesn't get
+ // the matching focus out event
+ (void)win->GetEventHandler()->ProcessEvent( event );
}
return FALSE;
if (g_focusWindow == this)
g_focusWindow = NULL;
- if (g_activeFrame == this)
- g_activeFrame = NULL;
-
if ( g_delayedFocus == this )
g_delayedFocus = NULL;
// focus handling
- if (m_focusWidget == NULL)
- m_focusWidget = m_widget;
-
- gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_in_event",
- GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
+ if (!GTK_IS_WINDOW(m_widget))
+ {
+ if (m_focusWidget == NULL)
+ m_focusWidget = m_widget;
+
+ gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_in_event",
+ GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
- gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_out_event",
- GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
+ gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_out_event",
+ GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
+ }
// connect to the various key and mouse handlers
#ifdef __WXGTK20__
gtk_signal_connect( GTK_OBJECT(widget), "scroll_event",
GTK_SIGNAL_FUNC(gtk_window_wheel_callback), (gpointer)this );
+ g_signal_connect(widget, "popup_menu",
+ G_CALLBACK(wxgtk_window_popup_menu_callback), this);
#endif
gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
// Update invalidated regions.
GtkUpdate();
- // Synthetize activate events.
- if ( g_sendActivateEvent != -1 )
- {
- bool activate = g_sendActivateEvent != 0;
-
- // do it only once
- g_sendActivateEvent = -1;
-
- wxTheApp->SetActive(activate, (wxWindow *)g_focusWindowLast);
- }
-
- if ( g_activeFrameLostFocus )
- {
- if ( g_activeFrame )
- {
- wxLogTrace(wxT("activate"), wxT("Deactivating frame %p (from idle)"), g_activeFrame);
- wxActivateEvent event(wxEVT_ACTIVATE, FALSE, g_activeFrame->GetId());
- event.SetEventObject(g_activeFrame);
- g_activeFrame->GetEventHandler()->ProcessEvent(event);
- g_activeFrame = NULL;
- }
- g_activeFrameLostFocus = FALSE;
- }
-
wxCursor cursor = m_cursor;
if (g_globalCursor.Ok()) cursor = g_globalCursor;
gtk_widget_hide( m_widget );
wxShowEvent eventShow(GetId(), show);
- eventShow.m_eventObject = this;
+ eventShow.SetEventObject(this);
GetEventHandler()->ProcessEvent(eventShow);
if (!parent)
parent = (wxWindow*)this;
- wxRegionIterator upd( m_updateRegion );
- while (upd)
+ if (GTK_WIDGET_MAPPED(parent->m_widget))
{
- GdkRectangle rect;
- rect.x = upd.GetX();
- rect.y = upd.GetY();
- rect.width = upd.GetWidth();
- rect.height = upd.GetHeight();
-
- gtk_paint_flat_box( parent->m_widget->style,
- pizza->bin_window,
- (GtkStateType)GTK_WIDGET_STATE(m_wxwindow),
- GTK_SHADOW_NONE,
- &rect,
- parent->m_widget,
- (char *)"base",
- 0, 0, -1, -1 );
-
- upd ++;
+ wxRegionIterator upd( m_updateRegion );
+ while (upd)
+ {
+ GdkRectangle rect;
+ rect.x = upd.GetX();
+ rect.y = upd.GetY();
+ rect.width = upd.GetWidth();
+ rect.height = upd.GetHeight();
+
+ gtk_paint_flat_box( parent->m_widget->style,
+ pizza->bin_window,
+ (GtkStateType)GTK_WIDGET_STATE(m_wxwindow),
+ GTK_SHADOW_NONE,
+ &rect,
+ parent->m_widget,
+ (char *)"base",
+ 0, 0, -1, -1 );
+
+ upd ++;
+ }
}
}
else
*is_waiting = FALSE;
}
-static void SetInvokingWindow( wxMenu *menu, wxWindowGTK *win )
+void SetInvokingWindow( wxMenu *menu, wxWindow* win )
{
menu->SetInvokingWindow( win );
+
wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
while (node)
{
wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") );
+ // NOTE: if you change this code, you need to update
+ // the same code in taskbar.cpp as well. This
+ // is ugly code duplication, I know,
+
SetInvokingWindow( menu, this );
menu->UpdateUI();