From 778aa3be4682e72a9c446da079cf7bd6390b1fb1 Mon Sep 17 00:00:00 2001 From: "blizzard%redhat.com" Date: Thu, 3 May 2001 12:04:56 +0000 Subject: [PATCH] Fix bug #76617. Some embedding apps can't get input focus. r=ccarlen,bryner sr=tor --- embedding/browser/gtk/src/EmbedPrivate.cpp | 123 +++++++++++-- embedding/browser/gtk/src/EmbedPrivate.h | 15 ++ embedding/browser/gtk/src/gtkmozembed2.cpp | 100 +++++++++- embedding/browser/webBrowser/nsWebBrowser.cpp | 10 - widget/src/gtk/nsWindow.cpp | 77 ++++---- widget/src/gtksuperwin/gtkmozarea.c | 174 +++++++++++++++++- widget/src/gtksuperwin/gtkmozarea.h | 6 + 7 files changed, 439 insertions(+), 66 deletions(-) diff --git a/embedding/browser/gtk/src/EmbedPrivate.cpp b/embedding/browser/gtk/src/EmbedPrivate.cpp index 91147202009..c04ccfc0786 100644 --- a/embedding/browser/gtk/src/EmbedPrivate.cpp +++ b/embedding/browser/gtk/src/EmbedPrivate.cpp @@ -43,6 +43,9 @@ #include #include +// for the focus hacking we need to do +#include + // for profiles #include @@ -448,6 +451,7 @@ EmbedPrivate::FindPrivateForBrowser(nsIWebBrowserChrome *aBrowser) void EmbedPrivate::ContentStateChange(void) { + // we don't attach listeners to chrome if (mListenersAttached && !mIsChrome) return; @@ -492,6 +496,69 @@ EmbedPrivate::ContentFinishedLoading(void) } } +// handle focus in and focus out events +void +EmbedPrivate::TopLevelFocusIn(void) +{ + nsCOMPtr piWin; + GetPIDOMWindow(getter_AddRefs(piWin)); + + if (!piWin) + return; + + nsCOMPtr focusController; + piWin->GetRootFocusController(getter_AddRefs(focusController)); + if (focusController) + focusController->SetActive(PR_TRUE); +} + +void +EmbedPrivate::TopLevelFocusOut(void) +{ + nsCOMPtr piWin; + GetPIDOMWindow(getter_AddRefs(piWin)); + + if (!piWin) + return; + + nsCOMPtr focusController; + piWin->GetRootFocusController(getter_AddRefs(focusController)); + if (focusController) + focusController->SetActive(PR_FALSE); +} + +void +EmbedPrivate::ChildFocusIn(void) +{ + nsCOMPtr piWin; + GetPIDOMWindow(getter_AddRefs(piWin)); + + if (!piWin) + return; + + piWin->Activate(); +} + +void +EmbedPrivate::ChildFocusOut(void) +{ + nsCOMPtr piWin; + GetPIDOMWindow(getter_AddRefs(piWin)); + + if (!piWin) + return; + + piWin->Deactivate(); + + // but the window is still active until the toplevel gets a focus + // out + nsCOMPtr focusController; + piWin->GetRootFocusController(getter_AddRefs(focusController)); + if (focusController) + focusController->SetActive(PR_TRUE); + +} + // Get the event listener for the chrome event handler. void @@ -500,28 +567,15 @@ EmbedPrivate::GetListener(void) if (mEventReceiver) return; - // get the web browser - nsCOMPtr webBrowser; - mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + nsCOMPtr piWin; + GetPIDOMWindow(getter_AddRefs(piWin)); - // get the content DOM window for that web browser - nsCOMPtr domWindow; - webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); - if (!domWindow) { - NS_WARNING("no dom window in content progress change\n"); + if (!piWin) return; - } - // get the private DOM window - nsCOMPtr domWindowPrivate = do_QueryInterface(domWindow); - // and the root window for that DOM window - nsCOMPtr rootWindow; - domWindowPrivate->GetPrivateRoot(getter_AddRefs(rootWindow)); - nsCOMPtr chromeHandler; - nsCOMPtr piWin(do_QueryInterface(rootWindow)); piWin->GetChromeEventHandler(getter_AddRefs(chromeHandler)); - + mEventReceiver = do_QueryInterface(chromeHandler); } @@ -587,6 +641,41 @@ EmbedPrivate::DetachListeners(void) mListenersAttached = PR_FALSE; } +nsresult +EmbedPrivate::GetPIDOMWindow(nsPIDOMWindow **aPIWin) +{ + *aPIWin = nsnull; + + // get the web browser + nsCOMPtr webBrowser; + mWindow->GetWebBrowser(getter_AddRefs(webBrowser)); + + // get the content DOM window for that web browser + nsCOMPtr domWindow; + webBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + if (!domWindow) + return NS_ERROR_FAILURE; + + // get the private DOM window + nsCOMPtr domWindowPrivate = do_QueryInterface(domWindow); + // and the root window for that DOM window + nsCOMPtr rootWindow; + domWindowPrivate->GetPrivateRoot(getter_AddRefs(rootWindow)); + + nsCOMPtr chromeHandler; + nsCOMPtr piWin(do_QueryInterface(rootWindow)); + + *aPIWin = piWin.get(); + + if (*aPIWin) { + NS_ADDREF(*aPIWin); + return NS_OK; + } + + return NS_ERROR_FAILURE; + +} + /* static */ nsresult EmbedPrivate::StartupProfile(void) diff --git a/embedding/browser/gtk/src/EmbedPrivate.h b/embedding/browser/gtk/src/EmbedPrivate.h index 833ab65eded..84779a98db5 100644 --- a/embedding/browser/gtk/src/EmbedPrivate.h +++ b/embedding/browser/gtk/src/EmbedPrivate.h @@ -43,6 +43,8 @@ class EmbedContentListener; class EmbedEventListener; class EmbedStream; +class nsPIDOMWindow; + class EmbedPrivate { public: @@ -83,6 +85,16 @@ class EmbedPrivate { // visibility is set. void ContentFinishedLoading(void); + // these let the widget code know when the toplevel window gets and + // looses focus. + void TopLevelFocusIn (void); + void TopLevelFocusOut(void); + + // these are when the widget itself gets focus in and focus out + // events + void ChildFocusIn (void); + void ChildFocusOut(void); + GtkMozEmbed *mOwningWidget; // all of the objects that we own @@ -135,6 +147,9 @@ class EmbedPrivate { void GetListener (void); void AttachListeners(void); void DetachListeners(void); + + // this will get the PIDOMWindow for this widget + nsresult GetPIDOMWindow (nsPIDOMWindow **aPIWin); static nsresult StartupProfile (void); static void ShutdownProfile(void); diff --git a/embedding/browser/gtk/src/gtkmozembed2.cpp b/embedding/browser/gtk/src/gtkmozembed2.cpp index 56560bd114e..92bcd661f98 100644 --- a/embedding/browser/gtk/src/gtkmozembed2.cpp +++ b/embedding/browser/gtk/src/gtkmozembed2.cpp @@ -32,6 +32,9 @@ // so we can do our get_nsIWebBrowser later... #include +// so we can get callbacks from the mozarea +#include + // class and instance initialization static void @@ -62,6 +65,26 @@ gtk_moz_embed_map(GtkWidget *widget); static void gtk_moz_embed_unmap(GtkWidget *widget); +static gint +handle_child_focus_in(GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GtkMozEmbed *aEmbed); + +static gint +handle_child_focus_out(GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GtkMozEmbed *aEmbed); + +// signal handlers for tracking the focus and and focus out events on +// the toplevel window. + +static void +handle_toplevel_focus_in (GtkMozArea *aArea, + GtkMozEmbed *aEmbed); +static void +handle_toplevel_focus_out(GtkMozArea *aArea, + GtkMozEmbed *aEmbed); + // globals for this type of widget static GtkBinClass *parent_class; @@ -103,7 +126,7 @@ gtk_moz_embed_class_init(GtkMozEmbedClass *klass) container_class = GTK_CONTAINER_CLASS(klass); bin_class = GTK_BIN_CLASS(klass); widget_class = GTK_WIDGET_CLASS(klass); - object_class = (GtkObjectClass *)klass; + object_class = GTK_OBJECT_CLASS(klass); parent_class = (GtkBinClass *)gtk_type_class(gtk_bin_get_type()); @@ -373,6 +396,34 @@ gtk_moz_embed_realize(GtkWidget *widget) if (embedPrivate->mURI.Length()) embedPrivate->LoadCurrentURI(); + + + // connect to the focus out event for the child + GtkWidget *child_widget = GTK_BIN(widget)->child; + gtk_signal_connect_while_alive(GTK_OBJECT(child_widget), + "focus_out_event", + GTK_SIGNAL_FUNC(handle_child_focus_out), + embed, + GTK_OBJECT(child_widget)); + gtk_signal_connect_while_alive(GTK_OBJECT(child_widget), + "focus_in_event", + GTK_SIGNAL_FUNC(handle_child_focus_in), + embed, + GTK_OBJECT(child_widget)); + + // connect to the toplevel focus out events for the child + GtkMozArea *mozarea = GTK_MOZAREA(child_widget); + gtk_signal_connect_while_alive(GTK_OBJECT(mozarea), + "toplevel_focus_in", + GTK_SIGNAL_FUNC(handle_toplevel_focus_in), + embed, + GTK_OBJECT(mozarea)); + + gtk_signal_connect_while_alive(GTK_OBJECT(mozarea), + "toplevel_focus_out", + GTK_SIGNAL_FUNC(handle_toplevel_focus_out), + embed, + GTK_OBJECT(mozarea)); } static void @@ -452,7 +503,54 @@ gtk_moz_embed_unmap(GtkWidget *widget) gdk_window_hide(widget->window); embedPrivate->Hide(); +} +static gint +handle_child_focus_in(GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GtkMozEmbed *aEmbed) +{ + EmbedPrivate *embedPrivate; + + embedPrivate = (EmbedPrivate *)aEmbed->data; + + embedPrivate->ChildFocusIn(); + + return FALSE; +} + +static gint +handle_child_focus_out(GtkWidget *aWidget, + GdkEventFocus *aGdkFocusEvent, + GtkMozEmbed *aEmbed) +{ + EmbedPrivate *embedPrivate; + + embedPrivate = (EmbedPrivate *)aEmbed->data; + + embedPrivate->ChildFocusOut(); + + return FALSE; +} + +static void +handle_toplevel_focus_in (GtkMozArea *aArea, + GtkMozEmbed *aEmbed) +{ + EmbedPrivate *embedPrivate; + embedPrivate = (EmbedPrivate *)aEmbed->data; + + embedPrivate->TopLevelFocusIn(); +} + +static void +handle_toplevel_focus_out(GtkMozArea *aArea, + GtkMozEmbed *aEmbed) +{ + EmbedPrivate *embedPrivate; + embedPrivate = (EmbedPrivate *)aEmbed->data; + + embedPrivate->TopLevelFocusOut(); } // Widget methods diff --git a/embedding/browser/webBrowser/nsWebBrowser.cpp b/embedding/browser/webBrowser/nsWebBrowser.cpp index c6c54115a7e..e48d2cbd062 100644 --- a/embedding/browser/webBrowser/nsWebBrowser.cpp +++ b/embedding/browser/webBrowser/nsWebBrowser.cpp @@ -1331,16 +1331,6 @@ nsEventStatus PR_CALLBACK nsWebBrowser::HandleEvent(nsGUIEvent *aEvent) switch(aEvent->message) { - case NS_ACTIVATE: { - browser->Activate(); - break; - } - - case NS_DEACTIVATE: { - browser->Deactivate(); - break; - } - case NS_PAINT: { nsRect *rect = NS_STATIC_CAST(nsPaintEvent *, aEvent)->rect; browser->FillBackground(*rect); diff --git a/widget/src/gtk/nsWindow.cpp b/widget/src/gtk/nsWindow.cpp index f630e33df6f..5994f043fb8 100644 --- a/widget/src/gtk/nsWindow.cpp +++ b/widget/src/gtk/nsWindow.cpp @@ -1109,28 +1109,30 @@ nsWindow::SetFocus(PRBool aRaise) printf("top moz area is %p\n", NS_STATIC_CAST(void *, top_mozarea)); #endif - // If there is a top_mozarea and it doesn't have focus then we're - // going to ignore this request if we're part of the browser. If - // we're embedded then we do grab focus on our toplevel window since - // it doesn't hurt anything and the widget has to have focus inside - // of the GtkWindow. If it doesn't then we will not get the right - // events when we do actually get focus. + // see if the toplevel window has focus + gboolean toplevel_focus = + gtk_mozarea_get_toplevel_focus(GTK_MOZAREA(top_mozarea)); + + // we need to grab focus or make sure that we get focus the next + // time that the toplevel gets focus. if (top_mozarea && !GTK_WIDGET_HAS_FOCUS(top_mozarea)) { - // If the toplevel window doesn't have an nsWindow data pointer - // then we are embedded. - gpointer data = gtk_object_get_data(GTK_OBJECT(toplevel), "nsWindow"); - // We're embedded so always set focus unconditionally. - if (!data) { - data = gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow"); - nsWindow *mozAreaWindow = NS_STATIC_CAST(nsWindow *, data); - mozAreaWindow->mBlockMozAreaFocusIn = PR_TRUE; - gtk_widget_grab_focus(top_mozarea); - mozAreaWindow->mBlockMozAreaFocusIn = PR_FALSE; - } - // We're not embedded. Just return. - else { - return NS_OK; - } + + gpointer data = gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow"); + nsWindow *mozAreaWindow = NS_STATIC_CAST(nsWindow *, data); + mozAreaWindow->mBlockMozAreaFocusIn = PR_TRUE; + gtk_widget_grab_focus(top_mozarea); + mozAreaWindow->mBlockMozAreaFocusIn = PR_FALSE; + + // !!hack alert!! This works around bugs in version of gtk older + // than 1.2.9, which is what most people use. If the toplevel + // window doesn't have focus then we have to unset the focus flag + // on this widget since it was probably just set incorrectly. + if (!toplevel_focus) + GTK_WIDGET_UNSET_FLAGS(top_mozarea, GTK_HAS_FOCUS); + + // always dispatch a set focus event + DispatchSetFocusEvent(); + return NS_OK; } if (mHasFocus) @@ -1285,11 +1287,15 @@ void nsWindow::HandleMozAreaFocusIn(void) // want to generate extra focus in events so just return. if (mBlockMozAreaFocusIn) return; + // otherwise, dispatch our focus events #ifdef DEBUG_FOCUS printf("nsWindow::HandleMozAreaFocusIn %p\n", NS_STATIC_CAST(void *, this)); #endif /* DEBUG_FOCUS */ - gJustGotActivate = PR_TRUE; + // we only set the gJustGotActivate signal if we're the toplevel + // window. embedding handles activate semantics for us. + if (mIsToplevel) + gJustGotActivate = PR_TRUE; DispatchSetFocusEvent(); } @@ -1334,7 +1340,10 @@ void nsWindow::HandleMozAreaFocusOut(void) nsCOMPtr focusWidgetGuard(focusWidget); focusWidget->DispatchLostFocusEvent(); - focusWidget->DispatchDeactivateEvent(); + // we only send activate/deactivate events for toplevel windows. + // activation and deactivation is handled by embedders. + if (mIsToplevel) + focusWidget->DispatchDeactivateEvent(); focusWidget->LoseFocus(); } } @@ -2715,30 +2724,30 @@ gint handle_mozarea_focus_in(GtkWidget * aWidget, gpointer aData) { if (!aWidget) - return PR_TRUE; + return FALSE; if (!aGdkFocusEvent) - return PR_TRUE; + return FALSE; nsWindow *widget = (nsWindow *)aData; if (!widget) - return PR_TRUE; + return FALSE; #ifdef DEBUG_FOCUS printf("handle_mozarea_focus_in\n"); #endif - // 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 + // set the flag since got a focus in event + GTK_WIDGET_SET_FLAGS(aWidget, GTK_HAS_FOCUS); + widget->HandleMozAreaFocusIn(); - return TRUE; + return FALSE; } gint handle_mozarea_focus_out(GtkWidget * aWidget, @@ -2750,17 +2759,17 @@ gint handle_mozarea_focus_out(GtkWidget * aWidget, #endif if (!aWidget) { - return PR_TRUE; + return FALSE; } if (!aGdkFocusEvent) { - return PR_TRUE; + return FALSE; } nsWindow *widget = (nsWindow *) aData; if (!widget) { - return PR_TRUE; + return FALSE; } // make sure that we unset our focus flag @@ -2768,7 +2777,7 @@ gint handle_mozarea_focus_out(GtkWidget * aWidget, widget->HandleMozAreaFocusOut(); - return TRUE; + return FALSE; } diff --git a/widget/src/gtksuperwin/gtkmozarea.c b/widget/src/gtksuperwin/gtkmozarea.c index cc68ba39941..507138c7c4c 100644 --- a/widget/src/gtksuperwin/gtkmozarea.c +++ b/widget/src/gtksuperwin/gtkmozarea.c @@ -16,16 +16,37 @@ * Owen Taylor and Christopher Blizzard. All Rights Reserved. */ #include "gtkmozarea.h" -#include +#include +#include static void gtk_mozarea_class_init (GtkMozAreaClass *klass); static void gtk_mozarea_init (GtkMozArea *mozarea); static void gtk_mozarea_realize (GtkWidget *widget); static void gtk_mozarea_unrealize (GtkWidget *widget); -static void gtk_mozarea_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static void gtk_mozarea_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); + +static void +attach_toplevel_listener(GtkMozArea *mozarea); + +static Window +get_real_toplevel(Window aWindow); + +static GdkFilterReturn +toplevel_window_filter(GdkXEvent *aGdkXEvent, + GdkEvent *aEvent, + gpointer data); GtkWidgetClass *parent_class = NULL; +enum { + TOPLEVEL_FOCUS_IN, + TOPLEVEL_FOCUS_OUT, + LAST_SIGNAL +}; + +static guint mozarea_signals[LAST_SIGNAL] = { 0 }; + GtkType gtk_mozarea_get_type (void) { @@ -55,8 +76,10 @@ static void gtk_mozarea_class_init (GtkMozAreaClass *klass) { GtkWidgetClass *widget_class; + GtkObjectClass *object_class; widget_class = GTK_WIDGET_CLASS (klass); + object_class = GTK_OBJECT_CLASS (klass); widget_class->realize = gtk_mozarea_realize; widget_class->unrealize = gtk_mozarea_unrealize; @@ -64,12 +87,31 @@ gtk_mozarea_class_init (GtkMozAreaClass *klass) parent_class = gtk_type_class(gtk_widget_get_type()); + /* set up our signals */ + + mozarea_signals[TOPLEVEL_FOCUS_IN] = + gtk_signal_new("toplevel_focus_in", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET(GtkMozAreaClass, toplevel_focus_in), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + mozarea_signals[TOPLEVEL_FOCUS_OUT] = + gtk_signal_new("toplevel_focus_out", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET(GtkMozAreaClass, toplevel_focus_out), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + gtk_object_class_add_signals(object_class, mozarea_signals, LAST_SIGNAL); + } static void gtk_mozarea_init (GtkMozArea *mozarea) { mozarea->superwin = NULL; + mozarea->toplevel_focus = FALSE; } static void @@ -84,8 +126,10 @@ gtk_mozarea_realize (GtkWidget *widget) mozarea = GTK_MOZAREA (widget); mozarea->superwin = gdk_superwin_new (gtk_widget_get_parent_window (widget), - widget->allocation.x, widget->allocation.y, - widget->allocation.width, widget->allocation.height); + widget->allocation.x, + widget->allocation.y, + widget->allocation.width, + widget->allocation.height); gdk_window_set_user_data (mozarea->superwin->shell_window, mozarea); widget->window = mozarea->superwin->shell_window; widget->style = gtk_style_attach (widget->style, widget->window); @@ -93,6 +137,9 @@ gtk_mozarea_realize (GtkWidget *widget) if we don't then it will be destroyed by both the superwin destroy method and the widget class destructor */ gdk_window_ref(widget->window); + + /* attach the toplevel X listener */ + attach_toplevel_listener(mozarea); } static void @@ -138,3 +185,122 @@ gtk_mozarea_new (GdkWindow *parent_window) return GTK_WIDGET (gtk_type_new (GTK_TYPE_MOZAREA)); } +gboolean +gtk_mozarea_get_toplevel_focus(GtkMozArea *area) +{ + g_return_val_if_fail(GTK_IS_MOZAREA(area), FALSE); + + return area->toplevel_focus; +} + +/* this function will attach a listener to this widget's real toplevel + window */ +static void +attach_toplevel_listener(GtkMozArea *mozarea) +{ + /* get the native window for this widget */ + GtkWidget *widget = GTK_WIDGET(mozarea); + Window window = GDK_WINDOW_XWINDOW(widget->window); + + Window toplevel = get_real_toplevel(window); + + /* check to see if this is an already registered window with the + type system. */ + GdkWindow *gdk_window = gdk_window_lookup(toplevel); + + /* This isn't our window? It is now, fool! */ + if (!gdk_window) { + /* import it into the type system */ + gdk_window = gdk_window_foreign_new(toplevel); + /* make sure that we are listening for the right events on it. */ + gdk_window_set_events(gdk_window, GDK_FOCUS_CHANGE_MASK); + } + + /* attach our passive filter. when the window is destroyed it will + automatically be removed. */ + + gdk_window_add_filter(gdk_window, toplevel_window_filter, mozarea); +} + +/* this function will try to find the real toplevel for a gdk window. */ +static Window +get_real_toplevel(Window aWindow) +{ + Window current = aWindow; + Atom atom; + + /* get the atom for the WM_STATE variable that you get on WM + managed windows. */ + + atom = XInternAtom(GDK_DISPLAY(), "WM_STATE", FALSE); + + while (current) { + Atom type = None; + int format; + unsigned long nitems, after; + unsigned char *data; + + Window root_return; + Window parent_return; + Window *children_return = NULL; + unsigned int nchildren_return; + + /* check for the atom on this window */ + XGetWindowProperty(GDK_DISPLAY(), current, atom, + 0, 0, /* offsets */ + False, /* don't delete */ + AnyPropertyType, + &type, &format, &nitems, &after, &data); + + /* did we get something? */ + if (type != None) { + XFree(data); + data = NULL; + /* ok, this is the toplevel window since it has the property set + on it. */ + break; + } + + /* what is the parent? */ + XQueryTree(GDK_DISPLAY(), current, &root_return, + &parent_return, &children_return, + &nchildren_return); + + if (children_return) + XFree(children_return); + + /* If the parent window of this window is the root window then + there is no window manager running so the current window is the + toplevel window. */ + if (parent_return == root_return) + break; + + current = parent_return; + } + + return current; +} + +static GdkFilterReturn +toplevel_window_filter(GdkXEvent *aGdkXEvent, + GdkEvent *aEvent, + gpointer data) +{ + XEvent *xevent = (XEvent *)aGdkXEvent; + GtkMozArea *mozarea = (GtkMozArea *)data; + + switch (xevent->xany.type) { + case FocusIn: + mozarea->toplevel_focus = TRUE; + gtk_signal_emit(GTK_OBJECT(mozarea), mozarea_signals[TOPLEVEL_FOCUS_IN]); + break; + case FocusOut: + mozarea->toplevel_focus = FALSE; + gtk_signal_emit(GTK_OBJECT(mozarea), mozarea_signals[TOPLEVEL_FOCUS_OUT]); + break; + default: + break; + } + + return GDK_FILTER_CONTINUE; +} diff --git a/widget/src/gtksuperwin/gtkmozarea.h b/widget/src/gtksuperwin/gtkmozarea.h index 25e01427ef9..c9757a747bc 100644 --- a/widget/src/gtksuperwin/gtkmozarea.h +++ b/widget/src/gtksuperwin/gtkmozarea.h @@ -38,15 +38,21 @@ struct _GtkMozArea { GtkWidget widget; GdkSuperWin *superwin; + gboolean toplevel_focus; }; struct _GtkMozAreaClass { GtkWindowClass window_class; + + /* signals */ + void (* toplevel_focus_in ) (GtkMozArea *area); + void (* toplevel_focus_out) (GtkMozArea *area); }; GtkType gtk_mozarea_get_type (void); GtkWidget *gtk_mozarea_new (); +gboolean gtk_mozarea_get_toplevel_focus(GtkMozArea *area); #ifdef __cplusplus }