зеркало из https://github.com/mozilla/gecko-dev.git
Fix bug #61782. Focus problems with gtk based plugins. This also cleans up a lot of other focus-related code as well. r=bryner, saari sr=scc
This commit is contained in:
Родитель
4f21917511
Коммит
4546cb78ec
|
@ -642,6 +642,7 @@ gint handle_key_press_event(GtkObject *w, GdkEventKey* event, gpointer p)
|
|||
nsKeyEvent kevent;
|
||||
nsWidget *win = (nsWidget*)p;
|
||||
|
||||
// if there's a focused window rewrite the event to use that window.
|
||||
if (win->sFocusWindow)
|
||||
win = win->sFocusWindow;
|
||||
|
||||
|
@ -870,9 +871,13 @@ handle_gdk_event (GdkEvent *event, gpointer data)
|
|||
// pass it to the nsWindow to be handled
|
||||
//
|
||||
nsWindow *grabbingWindow = nsWindow::GetGrabWindow();
|
||||
GdkWindow *grabbingGdkWindow = (GdkWindow *)grabbingWindow->GetNativeData(NS_NATIVE_WINDOW);
|
||||
// the grabbingWindow wasn't addrefed by the getter but we
|
||||
// want to keep a reference on it.
|
||||
nsCOMPtr<nsIWidget> grabbingWindowGuard(grabbingWindow);
|
||||
GdkWindow *grabbingGdkWindow =
|
||||
NS_STATIC_CAST(GdkWindow *,
|
||||
grabbingWindow->GetNativeData(NS_NATIVE_WINDOW));
|
||||
GtkWidget *grabbingMozArea = grabbingWindow->GetMozArea();
|
||||
NS_RELEASE(grabbingWindow);
|
||||
if (gtk_widget_child_of_gdk_window(current_grab, grabbingGdkWindow))
|
||||
{
|
||||
gdk_window_unref (event->any.window);
|
||||
|
@ -894,7 +899,6 @@ handle_gdk_event (GdkEvent *event, gpointer data)
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
// we need to make sure that if we're doing a gdk_pointer_grab on
|
||||
// a superwin that we check to make sure that we account for a
|
||||
// real GtkWidget being inside of it. the grab code in gtk that
|
||||
|
@ -906,17 +910,20 @@ handle_gdk_event (GdkEvent *event, gpointer data)
|
|||
// with a gtk scrollbar in it.
|
||||
|
||||
nsWindow *grabbingWindow = nsWindow::GetGrabWindow();
|
||||
// the grabbingWindow wasn't addrefed by the getter but we
|
||||
// want to keep a reference on it.
|
||||
nsCOMPtr<nsIWidget> grabbingWindowGuard(grabbingWindow);
|
||||
GtkWidget *tempWidget = NULL;
|
||||
if (grabbingWindow)
|
||||
{
|
||||
// get the GdkWindow that we are grabbing on
|
||||
GdkWindow *grabbingGdkWindow = (GdkWindow *)grabbingWindow->GetNativeData(NS_NATIVE_WINDOW);
|
||||
// release our nsIWidget
|
||||
NS_RELEASE(grabbingWindow);
|
||||
GdkWindow *grabbingGdkWindow =
|
||||
NS_STATIC_CAST(GdkWindow *,
|
||||
grabbingWindow->GetNativeData(NS_NATIVE_WINDOW));
|
||||
// only if this is a GtkWidget object
|
||||
if (GTK_IS_WIDGET(object))
|
||||
{
|
||||
tempWidget = (GtkWidget *)object;
|
||||
tempWidget = GTK_WIDGET(object);
|
||||
// check to see if this widget is the child of the GdkWindow
|
||||
// that we are grabbing on.
|
||||
if (gtk_widget_child_of_gdk_window(tempWidget, grabbingGdkWindow))
|
||||
|
@ -943,6 +950,13 @@ handle_gdk_event (GdkEvent *event, gpointer data)
|
|||
}
|
||||
gtk_grab_add(tempWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the gtk widget in question wasn't the child of the
|
||||
// grabbing window then the grabbing window gets it.
|
||||
dispatch_superwin_event(event, grabbingWindow);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
gtk_main_do_event (event);
|
||||
|
@ -958,14 +972,18 @@ dispatch_superwin_event(GdkEvent *event, nsWindow *window)
|
|||
{
|
||||
// Check to see whether or not we need to send this to the
|
||||
// toplevel window to get passed to the GtkWidget with focus.
|
||||
// This happens in the embedding case.
|
||||
if (!window->sFocusWindow)
|
||||
// This happens in the embedding case. If there's a superwin grab
|
||||
// in progress it gets the window events, not the gtk widget.
|
||||
if (!window->sFocusWindow && !window->GrabInProgress())
|
||||
{
|
||||
GtkWidget *mozArea = window->GetMozArea();
|
||||
NS_ASSERTION(mozArea, "Failed to get GtkMozArea for superwin event!\n");
|
||||
// get the toplevel window for that widget
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel(mozArea);
|
||||
// pass it off to gtk's event system and return
|
||||
gtk_propagate_event(mozArea, event);
|
||||
return;
|
||||
gboolean handled = gtk_widget_event(toplevel, event);
|
||||
if (handled)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2120,7 +2120,7 @@ nsWidget::OnFocusOutSignal(GdkEventFocus * aGdkFocusEvent)
|
|||
/* virtual */ void
|
||||
nsWidget::OnRealize(GtkWidget *aWidget)
|
||||
{
|
||||
printf("nsWidget::OnRealize(%p)\n",this);
|
||||
printf("nsWidget::OnRealize(%p)\n", NS_STATIC_CAST(void *, this));
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -82,16 +82,6 @@ extern "C" int usleep(unsigned int);
|
|||
|
||||
static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
|
||||
|
||||
gint handle_toplevel_focus_in (
|
||||
GtkWidget * aWidget,
|
||||
GdkEventFocus * aGdkFocusEvent,
|
||||
gpointer aData);
|
||||
|
||||
gint handle_toplevel_focus_out (
|
||||
GtkWidget * aWidget,
|
||||
GdkEventFocus * aGdkFocusEvent,
|
||||
gpointer aData);
|
||||
|
||||
gint handle_mozarea_focus_in (
|
||||
GtkWidget * aWidget,
|
||||
GdkEventFocus * aGdkFocusEvent,
|
||||
|
@ -120,8 +110,8 @@ nsWindow *nsWindow::mLastDragMotionWindow = NULL;
|
|||
// we get our drop after the leave.
|
||||
nsWindow *nsWindow::mLastLeaveWindow = NULL;
|
||||
|
||||
PRBool gJustGotActivate = PR_FALSE;
|
||||
PRBool gJustGotDeactivate = PR_TRUE;
|
||||
PRBool gJustGotDeactivate = PR_FALSE;
|
||||
PRBool gJustGotActivate = PR_FALSE;
|
||||
|
||||
static void printDepth(int depth) {
|
||||
int i;
|
||||
|
@ -1060,37 +1050,43 @@ NS_IMETHODIMP nsWindow::SetCursor(nsCursor aCursor)
|
|||
NS_IMETHODIMP
|
||||
nsWindow::SetFocus(void)
|
||||
{
|
||||
PRBool sendActivate = gJustGotActivate;
|
||||
gJustGotActivate = PR_FALSE;
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("nsWindow::SetFocus %p\n", this);
|
||||
printf("nsWindow::SetFocus %p\n", NS_STATIC_CAST(void *, this));
|
||||
#endif /* DEBUG_FOCUS */
|
||||
|
||||
if (mHasFocus)
|
||||
{
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("Already have focus.\n");
|
||||
#endif /* DEBUG_FOCUS */
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GtkWidget *top_mozarea = GetMozArea();
|
||||
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("top moz area is %p\n", NS_STATIC_CAST(void *, top_mozarea));
|
||||
#endif
|
||||
|
||||
if (top_mozarea)
|
||||
{
|
||||
if (!GTK_WIDGET_HAS_FOCUS(top_mozarea))
|
||||
{
|
||||
nsWindow *mozAreaWindow = (nsWindow *)gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow");
|
||||
mozAreaWindow->mBlockMozAreaFocusIn = PR_TRUE;
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("mozarea grabbing focus!\n");
|
||||
#endif
|
||||
mozAreaWindow->mBlockMozAreaFocusIn = PR_TRUE;
|
||||
gtk_widget_grab_focus(top_mozarea);
|
||||
mozAreaWindow->mBlockMozAreaFocusIn = PR_FALSE;
|
||||
// this will show the window if it's minimized and bring it to
|
||||
// the front of the stacking order.
|
||||
GetAttention();
|
||||
mozAreaWindow->mBlockMozAreaFocusIn = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mHasFocus)
|
||||
{
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("Returning: Already have focus.\n");
|
||||
#endif /* DEBUG_FOCUS */
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check to see if we need to send a focus out event for the old window
|
||||
if (sFocusWindow)
|
||||
{
|
||||
|
@ -1109,18 +1105,21 @@ nsWindow::SetFocus(void)
|
|||
#endif // USE_XIM
|
||||
|
||||
DispatchSetFocusEvent();
|
||||
if (/*gJustGotActivate &&*/ gJustGotDeactivate) {
|
||||
if (sendActivate) {
|
||||
DispatchActivateEvent();
|
||||
gJustGotActivate = PR_FALSE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("Returning:\n");
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsWindow::DispatchSetFocusEvent(void)
|
||||
{
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("nsWindow::DispatchSetFocusEvent %p\n", this);
|
||||
printf("nsWindow::DispatchSetFocusEvent %p\n", NS_STATIC_CAST(void *, this));
|
||||
#endif /* DEBUG_FOCUS */
|
||||
|
||||
nsGUIEvent event;
|
||||
|
@ -1142,7 +1141,7 @@ void nsWindow::DispatchLostFocusEvent(void)
|
|||
{
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("nsWindow::DispatchLostFocusEvent %p\n", this);
|
||||
printf("nsWindow::DispatchLostFocusEvent %p\n", NS_STATIC_CAST(void *, this));
|
||||
#endif /* DEBUG_FOCUS */
|
||||
|
||||
nsGUIEvent event;
|
||||
|
@ -1165,12 +1164,9 @@ void nsWindow::DispatchLostFocusEvent(void)
|
|||
void nsWindow::DispatchActivateEvent(void)
|
||||
{
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("nsWindow::DispatchActivateEvent %p\n", this);
|
||||
printf("nsWindow::DispatchActivateEvent %p\n", NS_STATIC_CAST(void *, this));
|
||||
#endif
|
||||
|
||||
if(!gJustGotDeactivate)
|
||||
return;
|
||||
|
||||
#ifdef USE_XIM
|
||||
IMEBeingActivate(PR_TRUE);
|
||||
#endif // USE_XIM
|
||||
|
@ -1199,14 +1195,13 @@ void nsWindow::DispatchActivateEvent(void)
|
|||
void nsWindow::DispatchDeactivateEvent(void)
|
||||
{
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("nsWindow::DispatchDeactivateEvent %p\n", this);
|
||||
printf("nsWindow::DispatchDeactivateEvent %p\n",
|
||||
NS_STATIC_CAST(void *, this));
|
||||
#endif
|
||||
#ifdef USE_XIM
|
||||
IMEBeingActivate(PR_TRUE);
|
||||
#endif // USE_XIM
|
||||
|
||||
gJustGotDeactivate = PR_TRUE;
|
||||
|
||||
nsGUIEvent event;
|
||||
event.message = NS_DEACTIVATE;
|
||||
event.widget = this;
|
||||
|
@ -1231,11 +1226,6 @@ void nsWindow::DispatchDeactivateEvent(void)
|
|||
|
||||
void nsWindow::HandleMozAreaFocusIn(void)
|
||||
{
|
||||
// If there's a shell window then we aren't embedded so all the
|
||||
// functionality is done in the focus handlers for the toplevel
|
||||
// window. Do nothing.
|
||||
if (mShell)
|
||||
return;
|
||||
// If we're getting this focus in as a result of a child superwin
|
||||
// getting called with SetFocus() this flag will be set. We don't
|
||||
// want to generate extra focus in events so just return.
|
||||
|
@ -1243,7 +1233,7 @@ void nsWindow::HandleMozAreaFocusIn(void)
|
|||
return;
|
||||
// otherwise, dispatch our focus events
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("nsWindow::HandleMozAreaFocusIn %p\n", this);
|
||||
printf("nsWindow::HandleMozAreaFocusIn %p\n", NS_STATIC_CAST(void *, this));
|
||||
#endif /* DEBUG_FOCUS */
|
||||
gJustGotActivate = PR_TRUE;
|
||||
DispatchSetFocusEvent();
|
||||
|
@ -1254,35 +1244,46 @@ void nsWindow::HandleMozAreaFocusIn(void)
|
|||
|
||||
void nsWindow::HandleMozAreaFocusOut(void)
|
||||
{
|
||||
// Working around unexplained missing calls to top level focus out
|
||||
gJustGotDeactivate = PR_TRUE;
|
||||
|
||||
// If there's a shell window then we aren't embedded so all the
|
||||
// functionality is done in the focus handlers for the toplevel
|
||||
// window. Do nothing.
|
||||
if (mShell)
|
||||
return;
|
||||
|
||||
// otherwise handle our focus out here.
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("nsWindow::HandleMozAreaFocusOut %p\n", this);
|
||||
printf("nsWindow::HandleMozAreaFocusOut %p\n", NS_STATIC_CAST(void *, this));
|
||||
#endif /* DEBUG_FOCUS */
|
||||
// if there's a window with focus, send a focus out event for that
|
||||
// window.
|
||||
if (sFocusWindow)
|
||||
{
|
||||
nsWidget *focusWidget = sFocusWindow;
|
||||
// Figure out of the focus widget is the child of this widget. If
|
||||
// it isn't then we don't send the event since it was already sent
|
||||
// earlier.
|
||||
PRBool isChild = PR_FALSE;
|
||||
GdkWindow *window;
|
||||
window = (GdkWindow *)sFocusWindow->GetNativeData(NS_NATIVE_WINDOW);
|
||||
while (window)
|
||||
{
|
||||
gpointer data = NULL;
|
||||
gdk_window_get_user_data(window, &data);
|
||||
if (GTK_IS_MOZAREA(data))
|
||||
{
|
||||
GtkWidget *tmpMozArea = GTK_WIDGET(data);
|
||||
if (tmpMozArea == mMozArea)
|
||||
{
|
||||
isChild = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
window = gdk_window_get_parent(window);
|
||||
}
|
||||
|
||||
NS_ADDREF(focusWidget);
|
||||
|
||||
focusWidget->DispatchLostFocusEvent();
|
||||
focusWidget->DispatchDeactivateEvent();
|
||||
focusWidget->LoseFocus();
|
||||
|
||||
NS_RELEASE(focusWidget);
|
||||
if (isChild)
|
||||
{
|
||||
nsWidget *focusWidget = sFocusWindow;
|
||||
nsCOMPtr<nsIWidget> focusWidgetGuard(focusWidget);
|
||||
|
||||
focusWidget->DispatchLostFocusEvent();
|
||||
focusWidget->DispatchDeactivateEvent();
|
||||
focusWidget->LoseFocus();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -1478,7 +1479,7 @@ nsWindow::dumpWindowChildren(Window aWindow, unsigned int depth)
|
|||
thisWindow);
|
||||
if (childWindow)
|
||||
{
|
||||
g_print("(shell_window for nsWindow %p)\n", childWindow);
|
||||
g_print("(shell_window for nsWindow %p)\n", NS_STATIC_CAST(void *, childWindow));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1503,12 +1504,12 @@ nsWindow::DumpWindowTree(void)
|
|||
// see where we are starting
|
||||
if (mShell)
|
||||
{
|
||||
g_print("dumping from shell for %p.\n", this);
|
||||
g_print("dumping from shell for %p.\n", NS_STATIC_CAST(void *, this));
|
||||
startWindow = mShell->window;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print("dumping from superwin for %p.\n", this);
|
||||
g_print("dumping from superwin for %p.\n", NS_STATIC_CAST(void *, this));
|
||||
startWindow = mSuperWin->shell_window;
|
||||
}
|
||||
Window window;
|
||||
|
@ -1517,7 +1518,7 @@ nsWindow::DumpWindowTree(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_print("no windows for %p.\n", this);
|
||||
g_print("no windows for %p.\n", NS_STATIC_CAST(void *, this));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1721,30 +1722,10 @@ NS_METHOD nsWindow::CreateNative(GtkObject *parentWidget)
|
|||
// set up all the focus handling
|
||||
|
||||
if (mShell) {
|
||||
// Track focus in event for the shell. We only need the focus in
|
||||
// event so that we can dispatch it to the mMozArea
|
||||
gtk_signal_connect(GTK_OBJECT(mShell),
|
||||
"focus_in_event",
|
||||
GTK_SIGNAL_FUNC(handle_toplevel_focus_in),
|
||||
this);
|
||||
gtk_signal_connect(GTK_OBJECT(mShell),
|
||||
"focus_out_event",
|
||||
GTK_SIGNAL_FUNC(handle_toplevel_focus_out),
|
||||
this);
|
||||
gtk_signal_connect(GTK_OBJECT(mShell),
|
||||
"property_notify_event",
|
||||
GTK_SIGNAL_FUNC(handle_toplevel_property_change),
|
||||
this);
|
||||
gtk_signal_connect(GTK_OBJECT(mShell),
|
||||
"key_press_event",
|
||||
GTK_SIGNAL_FUNC(handle_key_press_event),
|
||||
this);
|
||||
gtk_signal_connect(GTK_OBJECT(mShell),
|
||||
"key_release_event",
|
||||
GTK_SIGNAL_FUNC(handle_key_release_event),
|
||||
this);
|
||||
|
||||
|
||||
mask = (GdkEventMask) (GDK_PROPERTY_CHANGE_MASK |
|
||||
GDK_KEY_PRESS_MASK |
|
||||
GDK_KEY_RELEASE_MASK |
|
||||
|
@ -1757,7 +1738,7 @@ NS_METHOD nsWindow::CreateNative(GtkObject *parentWidget)
|
|||
}
|
||||
|
||||
if (mMozArea) {
|
||||
// track focus events for the moz area, too
|
||||
// track focus events for the moz area
|
||||
gtk_signal_connect(GTK_OBJECT(mMozArea),
|
||||
"focus_in_event",
|
||||
GTK_SIGNAL_FUNC(handle_mozarea_focus_in),
|
||||
|
@ -2648,84 +2629,6 @@ nsWindow::OnRealize(GtkWidget *aWidget)
|
|||
}
|
||||
}
|
||||
|
||||
gint handle_toplevel_focus_in(GtkWidget * aWidget,
|
||||
GdkEventFocus * aGdkFocusEvent,
|
||||
gpointer aData)
|
||||
{
|
||||
GtkWindow *window = NULL;
|
||||
GtkBin *bin = NULL;
|
||||
|
||||
if (!aWidget)
|
||||
return PR_TRUE;
|
||||
|
||||
if (!aGdkFocusEvent)
|
||||
return PR_TRUE;
|
||||
|
||||
nsWindow *widget = (nsWindow *)aData;
|
||||
|
||||
if (!widget)
|
||||
return PR_TRUE;
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("handle_toplevel_focus_in %p\n", widget);
|
||||
#endif /* DEBUG_FOCUS */
|
||||
|
||||
window = GTK_WINDOW(aWidget);
|
||||
bin = GTK_BIN(window);
|
||||
|
||||
gtk_widget_grab_focus(bin->child);
|
||||
|
||||
gJustGotActivate = PR_TRUE;
|
||||
if(gJustGotDeactivate) {
|
||||
widget->DispatchSetFocusEvent();
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
gint handle_toplevel_focus_out(GtkWidget * aWidget,
|
||||
GdkEventFocus * aGdkFocusEvent,
|
||||
gpointer aData)
|
||||
{
|
||||
if (!aWidget)
|
||||
return PR_TRUE;
|
||||
|
||||
if (!aGdkFocusEvent)
|
||||
return PR_TRUE;
|
||||
|
||||
nsWindow *widget = (nsWindow *) aData;
|
||||
|
||||
if (!widget)
|
||||
return PR_TRUE;
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("handle_toplevel_focus_out %p\n", widget);
|
||||
#endif
|
||||
|
||||
// addref the widget here since we might send > 1 event to it.
|
||||
NS_ADDREF(widget);
|
||||
|
||||
// if there's a window with focus, send a focus out event for that
|
||||
// window.
|
||||
if (widget->sFocusWindow)
|
||||
{
|
||||
nsWidget *focusWidget = widget->sFocusWindow;
|
||||
|
||||
NS_ADDREF(focusWidget);
|
||||
|
||||
focusWidget->DispatchLostFocusEvent();
|
||||
focusWidget->DispatchDeactivateEvent();
|
||||
focusWidget->LoseFocus();
|
||||
|
||||
NS_RELEASE(focusWidget);
|
||||
|
||||
}
|
||||
|
||||
NS_RELEASE(widget);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
gint handle_mozarea_focus_in(GtkWidget * aWidget,
|
||||
GdkEventFocus * aGdkFocusEvent,
|
||||
gpointer aData)
|
||||
|
@ -2748,9 +2651,13 @@ gint handle_mozarea_focus_in(GtkWidget * aWidget,
|
|||
// make sure that we set our focus flag
|
||||
GTK_WIDGET_SET_FLAGS(aWidget, GTK_HAS_FOCUS);
|
||||
|
||||
#ifdef DEBUG_FOCUS
|
||||
printf("aWidget is %p\n", NS_STATIC_CAST(void *, aWidget));
|
||||
#endif
|
||||
|
||||
widget->HandleMozAreaFocusIn();
|
||||
|
||||
return PR_TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint handle_mozarea_focus_out(GtkWidget * aWidget,
|
||||
|
@ -2780,7 +2687,7 @@ gint handle_mozarea_focus_out(GtkWidget * aWidget,
|
|||
|
||||
widget->HandleMozAreaFocusOut();
|
||||
|
||||
return PR_TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2893,7 +2800,6 @@ nsWindow::GetGrabWindow(void)
|
|||
{
|
||||
if (nsWindow::sIsGrabbing)
|
||||
{
|
||||
NS_ADDREF(sGrabWindow);
|
||||
return sGrabWindow;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -139,8 +139,8 @@ public:
|
|||
// virtual void OnButtonPressSignal(GdkEventButton * aGdkButtonEvent);
|
||||
void ShowCrossAtLocation(guint x, guint y);
|
||||
|
||||
// this will get the nsWindow with the grab. this will AddRef()
|
||||
// before returning.
|
||||
// this will get the nsWindow with the grab. The return will not be
|
||||
// addrefed.
|
||||
static nsWindow *GetGrabWindow(void);
|
||||
|
||||
virtual void DispatchSetFocusEvent(void);
|
||||
|
|
|
@ -16,14 +16,22 @@
|
|||
* Owen Taylor and Christopher Blizzard. All Rights Reserved. */
|
||||
|
||||
#include "gtkmozbox.h"
|
||||
#include <gtk/gtkmain.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
static void gtk_mozbox_class_init (GtkMozBoxClass *klass);
|
||||
static void gtk_mozbox_init (GtkMozBox *mozbox);
|
||||
static void gtk_mozbox_realize (GtkWidget *widget);
|
||||
static GdkFilterReturn gtk_mozbox_filter (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
gpointer data);
|
||||
static void gtk_mozbox_class_init (GtkMozBoxClass *klass);
|
||||
static void gtk_mozbox_init (GtkMozBox *mozbox);
|
||||
static void gtk_mozbox_realize (GtkWidget *widget);
|
||||
static void gtk_mozbox_set_focus (GtkWindow *window,
|
||||
GtkWidget *focus);
|
||||
static gint gtk_mozbox_key_press_event (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
static GdkFilterReturn gtk_mozbox_filter (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
gpointer data);
|
||||
static GtkWindow * gtk_mozbox_get_parent_gtkwindow (GtkMozBox *mozbox);
|
||||
|
||||
void (*parent_class_set_focus)(GtkWindow *, GtkWidget *);
|
||||
|
||||
GtkType
|
||||
gtk_mozbox_get_type (void)
|
||||
|
@ -54,10 +62,18 @@ static void
|
|||
gtk_mozbox_class_init (GtkMozBoxClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class;
|
||||
GtkWindowClass *window_class;
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (klass);
|
||||
window_class = GTK_WINDOW_CLASS (klass);
|
||||
|
||||
widget_class->realize = gtk_mozbox_realize;
|
||||
widget_class->realize = gtk_mozbox_realize;
|
||||
widget_class->key_press_event = gtk_mozbox_key_press_event;
|
||||
|
||||
/* save the parent class' set_focus method */
|
||||
parent_class_set_focus = window_class->set_focus;
|
||||
window_class->set_focus = gtk_mozbox_set_focus;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -111,6 +127,61 @@ gtk_mozbox_realize (GtkWidget *widget)
|
|||
gdk_window_add_filter (widget->window, gtk_mozbox_filter, mozbox);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_mozbox_set_focus (GtkWindow *window,
|
||||
GtkWidget *focus)
|
||||
{
|
||||
GtkMozBox *mozbox;
|
||||
GdkWindow *tmpWindow;
|
||||
GtkWindow *parentGtkWindow;
|
||||
|
||||
g_return_if_fail(window != NULL);
|
||||
g_return_if_fail(GTK_IS_MOZBOX(window));
|
||||
|
||||
mozbox = GTK_MOZBOX(window);
|
||||
|
||||
parentGtkWindow = gtk_mozbox_get_parent_gtkwindow (mozbox);
|
||||
|
||||
if (parentGtkWindow) {
|
||||
parent_class_set_focus(parentGtkWindow, focus);
|
||||
return;
|
||||
}
|
||||
|
||||
/* as a fall back just hand it off to our parent class */
|
||||
parent_class_set_focus(window, focus);
|
||||
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_mozbox_key_press_event (GtkWidget *widget,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
GtkWindow *window;
|
||||
GtkMozBox *mozbox;
|
||||
GtkWindow *parentWindow;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
window = GTK_WINDOW (widget);
|
||||
mozbox = GTK_MOZBOX (widget);
|
||||
|
||||
parentWindow = gtk_mozbox_get_parent_gtkwindow(mozbox);
|
||||
|
||||
/* give the focus window the chance to handle the event first. */
|
||||
if (parentWindow && parentWindow->focus_widget) {
|
||||
handled = gtk_widget_event (parentWindow->focus_widget, (GdkEvent*) event);
|
||||
}
|
||||
|
||||
/* pass it off to the parent widget */
|
||||
if (!handled) {
|
||||
gdk_window_unref(event->window);
|
||||
event->window = mozbox->parent_window;
|
||||
gdk_window_ref(event->window);
|
||||
gdk_event_put((GdkEvent *)event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
gtk_mozbox_filter (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
|
@ -134,6 +205,23 @@ gtk_mozbox_filter (GdkXEvent *xevent,
|
|||
}
|
||||
}
|
||||
|
||||
static GtkWindow *
|
||||
gtk_mozbox_get_parent_gtkwindow (GtkMozBox *mozbox)
|
||||
{
|
||||
GdkWindow *tmpWindow;
|
||||
/* look for a parent GtkWindow in the heirarchy */
|
||||
tmpWindow = mozbox->parent_window;
|
||||
while (tmpWindow) {
|
||||
gpointer data = NULL;
|
||||
gdk_window_get_user_data(tmpWindow, &data);
|
||||
if (data && GTK_IS_WINDOW(data)) {
|
||||
return GTK_WINDOW(data);
|
||||
}
|
||||
tmpWindow = gdk_window_get_parent(tmpWindow);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
gtk_mozbox_new (GdkWindow *parent_window)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче