Bug 1209574 - Switch GeckoInputConnection for each new GeckoView; r=esawin

The GeckoEditable instance doesn't change for each nsWindow instance.
However, because a GeckoInputConnection is associated with a GeckoView,
when we create a new GeckoView, we need to attach a new
GeckoInputConnection to the existing nsWindow's GeckoEditable. This
patch makes us do that inside nsWindow::Natives::Open by calling
GeckoEditable.OnViewChange.
This commit is contained in:
Jim Chen 2015-10-07 08:57:31 -04:00
parent 56c96b7686
commit 8527258e66
5 changed files with 72 additions and 18 deletions

View File

@ -366,12 +366,41 @@ final class GeckoEditable
Editable.class.getClassLoader(),
PROXY_INTERFACES, this);
LayerView v = GeckoAppShell.getLayerView();
mListener = GeckoInputConnection.create(v, this);
mIcRunHandler = mIcPostHandler = ThreadUtils.getUiHandler();
}
@WrapForJNI
/* package */ void onViewChange(final GeckoView v) {
if (DEBUG) {
// Called by nsWindow.
ThreadUtils.assertOnGeckoThread();
Log.d(LOGTAG, "onViewChange(" + v + ")");
}
final GeckoEditableListener newListener = GeckoInputConnection.create(v, this);
geckoPostToIc(new Runnable() {
@Override
public void run() {
if (DEBUG) {
Log.d(LOGTAG, "onViewChange (set listener)");
}
// Make sure there are no other things going on
mActionQueue.syncWithGecko();
mListener = newListener;
}
});
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (DEBUG) {
Log.d(LOGTAG, "onViewChange (set IC)");
}
v.setInputConnectionListener((InputConnectionListener) newListener);
}
});
}
private boolean onIcThread() {
return mIcRunHandler.getLooper() == Looper.myLooper();
}
@ -863,17 +892,7 @@ final class GeckoEditable
geckoPostToIc(new Runnable() {
@Override
public void run() {
// Make sure there are no other things going on
mActionQueue.syncWithGecko();
// Set InputConnectionHandler in notifyIMEContext because
// GeckoInputConnection.notifyIMEContext calls restartInput() which will invoke
// InputConnectionHandler.onCreateInputConnection
GeckoView v = GeckoAppShell.getLayerView();
if (v != null) {
mListener = GeckoInputConnection.create(v, GeckoEditable.this);
v.setInputConnectionListener((InputConnectionListener) mListener);
mListener.notifyIMEContext(state, typeHint, modeHint, actionHint);
}
mListener.notifyIMEContext(state, typeHint, modeHint, actionHint);
}
});
}

View File

@ -115,7 +115,7 @@ public class GeckoView extends LayerView
@WrapForJNI
private static final class Window extends JNIObject {
static native void open(Window instance, int width, int height);
static native void open(Window instance, GeckoView view, int width, int height);
static native void setLayerClient(Object client);
@Override protected native void disposeNative();
}
@ -225,10 +225,11 @@ public class GeckoView extends LayerView
final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
Window.open(window, metrics.widthPixels, metrics.heightPixels);
Window.open(window, this, metrics.widthPixels, metrics.heightPixels);
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY, Window.class,
"open", window, metrics.widthPixels, metrics.heightPixels);
"open", window, GeckoView.class, this,
metrics.widthPixels, metrics.heightPixels);
}
}

View File

@ -752,6 +752,14 @@ auto GeckoEditable::OnTextChange(mozilla::jni::String::Param a0, int32_t a1, int
return mozilla::jni::Method<OnTextChange_t>::Call(this, nullptr, a0, a1, a2, a3);
}
constexpr char GeckoEditable::OnViewChange_t::name[];
constexpr char GeckoEditable::OnViewChange_t::signature[];
auto GeckoEditable::OnViewChange(mozilla::jni::Object::Param a0) const -> void
{
return mozilla::jni::Method<OnViewChange_t>::Call(this, nullptr, a0);
}
constexpr char GeckoEditableListener::name[];
constexpr char GeckoJavaSampler::name[];

View File

@ -1796,6 +1796,24 @@ public:
auto OnTextChange(mozilla::jni::String::Param, int32_t, int32_t, int32_t) const -> void;
public:
struct OnViewChange_t {
typedef GeckoEditable Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::Object::Param> Args;
static constexpr char name[] = "onViewChange";
static constexpr char signature[] =
"(Lorg/mozilla/gecko/GeckoView;)V";
static const bool isStatic = false;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
auto OnViewChange(mozilla::jni::Object::Param) const -> void;
};
class GeckoEditableListener : public mozilla::jni::Class<GeckoEditableListener>
@ -2457,11 +2475,12 @@ public:
typedef void SetterType;
typedef mozilla::jni::Args<
Window::Param,
GeckoView::Param,
int32_t,
int32_t> Args;
static constexpr char name[] = "open";
static constexpr char signature[] =
"(Lorg/mozilla/gecko/GeckoView$Window;II)V";
"(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;II)V";
static const bool isStatic = true;
static const bool isMultithreaded = true;
static const mozilla::jni::ExceptionMode exceptionMode =

View File

@ -186,6 +186,7 @@ public:
// Create and attach a window.
static void Open(const jni::ClassObject::LocalRef& cls,
GeckoView::Window::Param gvWindow,
GeckoView::Param view,
int32_t width, int32_t height);
// Set the active layer client object
@ -200,6 +201,7 @@ public:
void
nsWindow::Natives::Open(const jni::ClassObject::LocalRef& cls,
GeckoView::Window::Param gvWindow,
GeckoView::Param view,
int32_t width, int32_t height)
{
MOZ_ASSERT(NS_IsMainThread());
@ -210,6 +212,10 @@ nsWindow::Natives::Open(const jni::ClassObject::LocalRef& cls,
if (gGeckoViewWindow) {
// Should have been created the first time.
MOZ_ASSERT(gGeckoViewWindow->mNatives);
// Associate our previous GeckoEditable with the new GeckoView.
gGeckoViewWindow->mEditable->OnViewChange(view);
AttachNative(GeckoView::Window::LocalRef(cls.Env(), gvWindow),
gGeckoViewWindow->mNatives.get());
return;
@ -252,6 +258,7 @@ nsWindow::Natives::Open(const jni::ClassObject::LocalRef& cls,
// Create GeckoEditable for the new nsWindow/GeckoView pair.
gGeckoViewWindow->mEditable = GeckoEditable::New();
gGeckoViewWindow->mEditable->OnViewChange(view);
AttachNative(GeckoView::Window::LocalRef(cls.Env(), gvWindow),
gGeckoViewWindow->mNatives.get());