Closed
Bug 53989
Opened 23 years ago
Closed 22 years ago
XIM: over-the-spot hangs with VJE3.0 and ATOK X
Categories
(Core :: Internationalization, defect, P3)
Tracking
()
VERIFIED
FIXED
People
(Reporter: masaki.katakai, Assigned: masaki.katakai)
References
Details
(Keywords: hang, inputmethod, intl, Whiteboard: [rtm-])
Attachments
(8 files)
4.00 KB,
patch
|
Details | Diff | Splinter Review | |
642 bytes,
patch
|
Details | Diff | Splinter Review | |
987 bytes,
patch
|
Details | Diff | Splinter Review | |
16.52 KB,
patch
|
Details | Diff | Splinter Review | |
16.36 KB,
patch
|
Details | Diff | Splinter Review | |
50.42 KB,
patch
|
Details | Diff | Splinter Review | |
50.45 KB,
patch
|
Details | Diff | Splinter Review | |
9.28 KB,
patch
|
Details | Diff | Splinter Review |
Japanese user reported this problem as http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=285 When over-the-spot style, Mozill hangs when - click hyper link or - start Composer It seems that focused window is destroyed and it causes this problem, some japanese IMEs, VJE3.0 and ATOK X for Linux do not handle this case properly and finally Mozilla hangs. I made a patch already and the japanese user had verified. I'll ask tajima@eng.sun.com to review the patch, then post the patch.
Updated•23 years ago
|
Status: NEW → ASSIGNED
Comment 1•23 years ago
|
||
Comment 2•23 years ago
|
||
The patch was sent to a module owner for code review. Teruko-san, please update the status whiteboard accordingly for both this bug and 53990. Thanks.
Comment 3•23 years ago
|
||
Though I could not reproduce the problem on HPUX, neither could I see any problem after I apply the patch. I have no objection to the patch.
Comment 4•23 years ago
|
||
Thanks Shanjian for testing on HP-UX. Can I send a request for check-in approval with r=shanjian, then?
Comment 5•23 years ago
|
||
r=somebody@netscape.com has been wanted.
Comment 6•23 years ago
|
||
the code looks ok to me, although I don't have any good way of testing it.
Comment 7•23 years ago
|
||
sr=blizzard pending pav looking at it
Comment 8•23 years ago
|
||
chris, pavlov already looked at it and he seemed to give r= with his 10/02 comment.
Comment 9•23 years ago
|
||
No wonder but it has been pending for code review and approval more than two weeks.
Keywords: approval
Comment 11•23 years ago
|
||
Need a real review, a real super review, a description of why this matters for the Netscape 6 release, and some information about testing done on the patch.
Whiteboard: [rtm+] → [rtm need info]
Comment 12•23 years ago
|
||
shanjian and erik - can you review the code again. tajima- can you explain why this is important ? what will happen if we don't fix it ? what will happen if something wrong in the patch ? How many people have test it ? Any people from Japan have test the patch ?
Comment 13•23 years ago
|
||
In the patch, there is a line like this: if(oldw != mBounds.width && oldh != mBounds.height) { Should it be as follows: if ((oldw != mBounds.width) || (oldh != mBounds.height)) { Also, oldy used to be set to spot.y, which had mCursorPosition.height added to it, but now it doesn't have the height added. Is this needed? Has this fix been tested with popular input methods on popular OS's in Japan? What about Korean and Chinese?
Comment 14•23 years ago
|
||
Many users using VJE for Japanese input would hate mozilla without fixing the problem, at lease 5 people(shanjian, Katakai, 2 japanese users, and myself) has tested the patch, specifically I tested English/French/Germany locales, too. HP-UX, Solaris, Redhat6.1/6.2 and FreeBSD are covered. Erik, the if condition should be corrected as you pointed, thanks. As to oldy, now it has previous mCursorPosition.y, and is compared to new mCursorPosition.y. This logic is correct. But, before the patch, it has previous mCursorPosition.y + mCursorPosition.height and is compared to new mCustorPosition.y. That was wrong, and is corrected.
Comment 15•23 years ago
|
||
mark it as rtm+ again. pdt, does tajima's answer ok for you. Call him at 650-786-9182 if you still have question
Whiteboard: [rtm need info] → [rtm+]
Comment 16•23 years ago
|
||
Is erik giving his a= ? Can anyone give a good r= ? Frankly, neither blizzard's comments nor pav's make me feel confident in this patch to take it on the N6 branch. Marking [rtm need info]
Whiteboard: [rtm+] → [rtm need info]
Comment 17•23 years ago
|
||
Let's see a new patch (diff -u format please) with the fix to that logic bug Erik found. /be
Comment 18•23 years ago
|
||
pav and blizzard should be able to review this code to make sure it does not break the non-IME code paths. erik should be able to review for this including the IME impact. Masaki (katakai), Will you please review this too?
Comment 19•23 years ago
|
||
+ // In over-the-spot style, pre-edit can not be drawn properly when + // IMESetFocusWidget() is called at height=1 and width=1 Who sets height and width to 1? Where is that code? + // After resizing, we need to call SetPreeditArea() again + if(oldw != mBounds.width && oldh != mBounds.height) { + GdkWindow *gdkWindow = (GdkWindow*)this->GetNativeData(NS_NATIVE_WINDOW); + if (mXIC && gdkWindow) { + mXIC->SetPreeditArea(0, 0, + (int)((GdkWindowPrivate*)gdkWindow)->width, + (int)((GdkWindowPrivate*)gdkWindow)->height); + } + } + oldw = mBounds.width; + oldh = mBounds.height; The 2 statements above should be inside the "if" statement to avoid setting them redundantly. + oldx = compEvent.theReply.mCursorPosition.x; + oldy = compEvent.theReply.mCursorPosition.y; Here again, these 2 should be inside the "if". ! gPreeditFontset = gdk_fontset_load("-*-*-*-r-*-*-16-*-*-*-*-*-*-*"); Is this change needed to solve the hanging problem? Please limit the patch to the bare minimum. nsWidget::IMEDestroyIC() { if (!mXIC) return; + if (mIsToplevel == PR_TRUE) { delete mXIC; + } else { + nsWidget *widget = mXIC->GetFocusWidget(); + if (widget && widget == this && mIMEShellWidget) { + mXIC->SetFocusWidget(mIMEShellWidget); + mXIC->UnsetFocusWidget(); + } } mXIC = 0; } What is this patch doing? Why is this necessary? Is there a bug in VJE? Is this a workaround for a bug in VJE? Do we need the resizing part as well as this part? Or is this part enough to solve the hanging problem? What is the mIMEShellWidget?
Comment 20•23 years ago
|
||
The width and height are set to 1 when the widget is set to size 0x0. That's illegal in X so we set it to 1x1.
Assignee | ||
Comment 21•23 years ago
|
||
Assignee | ||
Comment 22•23 years ago
|
||
Erik and Chris, thank you very much for reviewing and comments. Yes, the patch contains changes for 53990. I've attached patch only for this problem. Only IMEDestroyIC() part is necessary. I'd like to explain how this problem happens, when a hyper link is clicked, (1) nsWidget::IMESetFocusWidget() is invoked for setting focus Mozilla sends focus_window (the widget) to IME server IME server creates pre-edit window as a child of the focus_window (2) the widget (contains the hyper link) will be destroyed but, IME server keeps the focus_window of (1) (3) new widget will be created for new page nsWidget::IMESetFocusWidget() is invoked for setting focus In ATOKX case, IME server does XReparentWindow() of pre-edit window for previous focus_window to new focus_window, however, the previous focus_window is invalid, already destroyed in (2) and it causes X error. I think problems exist in IME server, VLE and ATOKX. IME server may be able to check the focus_window is valid or not before calling XReparentWindow(). I understand kinput2 does the check. However, we should put a workaround into Mozilla because VJE and ATOKX are already shipped and used, and it would be difficult to ask IME vendor to fix this problem. mIMEShellWidget is a shell widget of Mozilla window. IC is shared among widgets on the shell widget. nsWidget::IMEDestroyIC() { if (!mXIC) return; if (mIsToplevel == PR_TRUE) { delete mXIC; } else { nsWidget *widget = mXIC->GetFocusWidget(); // when focused widget == this widget // and shell widget exists if (widget && widget == this && mIMEShellWidget) { // set focus window is the shell widget // to clear the previous focus_window mXIC->SetFocusWidget(mIMEShellWidget); // call gdk_im_end() mXIC->UnsetFocusWidget(); } } mXIC = 0; }
Comment 23•23 years ago
|
||
Masaki, thanks for the explanation. I still have questions. > when a hyper link is clicked, > > (1) nsWidget::IMESetFocusWidget() is invoked for setting focus > Mozilla sends focus_window (the widget) to IME server > IME server creates pre-edit window as a child of the focus_window Which hyperlink are you clicking? Any hyperlink? Which widget is being focussed? A text field? Which one? Or a shell? In the fix, why are you setting the focus to the shell widget and then unsetting the focus? Would it work if you only unset the focus (without setting focus to the shell)? Or do you have to do both of those (set focus to shell and unset focus)? How popular do you believe VJE and ATOK are on Unix? What percentage of users are using them? (Please give us a rough estimate.)
Assignee | ||
Comment 24•23 years ago
|
||
Hi Erik, > Which hyperlink are you clicking? Any hyperlink? Yes, Any hyperlink. > Which widget is being focussed? A text field? Which one? Or a shell? Widget which has a hyperlink. Not only text field. Currently widget that may take an input focus will have an IC. The IC is shared in shell widget. > Would it work if you only unset the focus (without setting focus to the shell)? Or do you have to do both of those (set focus to shell and unsetfocus)? good question. I missed to mention about this. I was also thinking this problem could be solved by only unsetfocus. However, it couldn't. It seems that IM server still keep the previous focus_window even when we call unsetfocus. > How popular do you believe VJE and ATOK are on Unix? What percentage of users are using them? (Please give us a rough estimate.) I guess about 5%. kinput2 based IME engines are free so bundled in Linux distribution. VJE and ATOK X are not free. I think it is important to fully support such commercial IMEs. In addition, this problem was posted in the major mailing-list of Linux in Japan. So many people may think such serious problem will be fixed by RTM. Is it better to ask submitter of the original problem to verify the revised patch again? The original patch was verified one month ago. I've verified the patch with ATOK X. However, I don't have VJE.
Comment 25•23 years ago
|
||
This may also affect non-Linux Unices because some commercial Unices have licensde and bundled ATOK and/or VJE. cc'ing jdunn and jaworski.
Comment 26•23 years ago
|
||
> > Which widget is being focussed? A text field? Which one? Or a shell? > > Widget which has a hyperlink. Let's suppose we have an HTML document with a hyperlink. Which widget is then being focussed? The widget that surrounds the entire HTML document? > Is it better to ask submitter of the original problem to verify the > revised patch again? The original patch was verified one month ago. > I've verified the patch with ATOK X. However, I don't have VJE. Yes, please ask the original bug reporter to verify the latest fix with VJE. When a document presentation is being destroyed, are the widgets destroyed in a particular order? For example, small internal widgets (subwindows) first, and then the shell last? I'm just concerned about setting the focus on the shell widget (mIMEShellWidget) when IMEDestroyIC is being called. Are you absolutely sure that mIMEShellWidget is valid at that point and not in the process of being destroyed itself?
Assignee | ||
Comment 27•23 years ago
|
||
> Let's suppose we have an HTML document with a hyperlink. Which widget is then > being focussed? The widget that surrounds the entire HTML document? not exact HTML widget. It will be called from http://lxr.mozilla.org/mozilla/source/layout/html/base/src/nsPresShell.cpp#2167 I don't have any idea what this widget is. What is domWindow? > Yes, please ask the original bug reporter to verify the latest fix with VJE. I've asked. But I couldn't get any reply from him. I'll ask again. > When a document presentation is being destroyed, are the widgets destroyed in a > particular order? For example, small internal widgets (subwindows) first, and > then the shell last? I'm just concerned about setting the focus on the shell I verified the shell widget is always destroyed at last. > widget (mIMEShellWidget) when IMEDestroyIC is being called. Are you absolutely > sure that mIMEShellWidget is valid at that point and not in the process of being > destroyed itself? If mIMEShellWidget (mIsToplevel=PR_TRUE) is destroyed, IMEDestroyIC() just call delete mXIC; if (mIsToplevel == PR_TRUE) { delete mXIC; } else { } mXIC = 0; Even if mIMEShellWidget is destroyed before (by above codes), mXIC is 0 so that the following code will return. The codes about setting focus will not be executed. if(!mXIC) return;
Comment 28•23 years ago
|
||
r=erik OK, I am satisfied that the 2nd patch (10/29/00 21:47) is safe and necessary. I am also satisfied with Masaki's testing on ATOK. I believe we should get this into the branch. If desired, we can get this into the trunk first for further testing. Brendan, do we have permission to land the 2nd patch on the trunk? PDT, do we have permission to land it on the branch? Marking [rtm+] to get it on PDT's radar.
Whiteboard: [rtm need info] → [rtm+] [r=erik]
Comment 29•23 years ago
|
||
Umm, you need a SR= as well to get on rtm+. Get it quickly before the PDT bitchslaps you back to rtm need info.
Whiteboard: [rtm+] [r=erik] → [rtm+] [r=erik], NEED SR=
Comment 30•23 years ago
|
||
Erik was not explicit but meant to ask Brendan for sr= in Erik's last comment. The second patch has been carefully reviewed by Erik: http://bugzilla.mozilla.org/showattachment.cgi?attach_id=18269
Comment 31•23 years ago
|
||
Changing back to [rtm need info] since we don't have an SR= yet. Brendan? Chris?
Whiteboard: [rtm+] [r=erik], NEED SR= → [rtm need info] [r=erik], NEED SR=
Comment 32•23 years ago
|
||
I can sr=brendan@mozilla.org the second patch. Is the first patch unnecessary even on the trunk? /be
Whiteboard: [rtm need info] [r=erik], NEED SR= → [rtm+] [r=erik], NEED SR=
Updated•23 years ago
|
Whiteboard: [rtm+] [r=erik], NEED SR= → [rtm+] [r=erik], [rtm+]
Comment 33•23 years ago
|
||
The first patch had pieces that were necessary for bug 53990. I've added comments to that bug.
Updated•23 years ago
|
Whiteboard: [rtm+] [r=erik], [rtm+] → [rtm+] [r=erik], sr=brendan
Comment 34•23 years ago
|
||
Erik, Please check into the trunk.
Comment 35•23 years ago
|
||
Xianglan, this is the bug I was talking before. I do not have ATOK installed in my linux machine. After erik checks in trunk build, would you verify this in the trunk build? Thanks.
Comment 36•23 years ago
|
||
Fix checked into trunk. Not marking FIXED yet, since it's not in the branch yet.
Comment 37•23 years ago
|
||
This second minimal patch is very safe: (1) It's Unix only (2) Will only be executed if an IME input context is being used (i.e. only for Japanese, Chinese or Korean input) (3) Just sets and unsets focus on an IME widget to make sure 3rd party IMEs know the input focus window is invalid ATOK and VJE are 2 of the most popular Windows Japanese IMEs that have been ported to Linux and other Unix systems. Without this fix, these Mozilla is unusable with these IMEs. In case PDT is reviewing without the diff attachment, here is the diff: diff -c -r1.242 nsWidget.cpp *** nsWidget.cpp 2000/10/28 22:16:45 1.242 --- nsWidget.cpp 2000/10/30 05:42:31 *************** *** 3146,3151 **** --- 3146,3157 ---- if (!mXIC) return; if (mIsToplevel == PR_TRUE) { delete mXIC; + } else { + nsWidget *widget = mXIC->GetFocusWidget(); + if (widget && widget == this && mIMEShellWidget) { + mXIC->SetFocusWidget(mIMEShellWidget); + mXIC->UnsetFocusWidget(); + } } mXIC = 0; }
Assignee | ||
Comment 38•23 years ago
|
||
Thank you for integration, Erik. Xianglan, to set over-the-spot, please specify in your prefs.js as below, user_pref("xim.input_style", "over-the-spot"); Clicking a hyper link causes Mozilla hangs without this fix because ATOKX XIM server exits by X error.
Comment 39•23 years ago
|
||
Masaki, Please add comments on any other testing you or others have done. Thanks.
Comment 40•23 years ago
|
||
Compared 2000110308-Mtrunk and 2000103009-mn6 build. On my RH6.2J, where atok12 is installed, Netscape 6 doesn't hang even without the fix. And after the fix, Netscape 6 doesn't have this problem either.
Comment 41•23 years ago
|
||
Shanjian, How about HPUX? Could you check today's trunk build on HPUX? Thanks.
Comment 42•23 years ago
|
||
Shanjian, When you tried this on HP earlier were you using over-the-spot: user_pref("xim.input_style", "over-the-spot");
Comment 43•23 years ago
|
||
Actually, the pref for over-the-spot style doesn't make any difference for linux build on my environment. IME still behaves in the same way as on-the-spot after I include the pref in prefs.js file.
Comment 44•23 years ago
|
||
As I mentioned before, this problem does not exist on HPUX. I did set over-the-spot for HPUX, that is the only IME option working for HP. I am trying to reproduce the problem on Linux now.
Comment 45•23 years ago
|
||
I just tried atok12 which I found from redhat6.2J commercial CD, I could not reproduce the problem. We might have to ask Katakai to verify it.
Comment 46•23 years ago
|
||
Katakai-san and Tajima-san, would you please verify this fix in today's trunk build? Thanks.
Assignee | ||
Comment 47•23 years ago
|
||
I've verified this problem on 2000110221 with ATOK X. I can reproduce on 2000102621 but not on 2000110221. ji and Shanjian, ATOK12 in Redhat62J CD is "ATOK12SE", which uses kinput2 interface and it's not "ATOK X".
Assignee | ||
Comment 48•23 years ago
|
||
I'll try Solaris build on Monday. Also I'll get VJE IME.
Comment 49•23 years ago
|
||
PDT marking [rtm++]. Please check in to the branch ASAP.
Whiteboard: [rtm+] [r=erik], sr=brendan → [rtm++] [r=erik], sr=brendan
Comment 50•23 years ago
|
||
Erik is gone for the day. Bob Jung asked me to check this in. I'm working with Robert Churchill to build a current branch with the patch. As soon as we build and do normal checking testing it will be checked in.
Comment 51•23 years ago
|
||
Fixed.
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Comment 52•23 years ago
|
||
Masaki (katakai), per Teruko's request I am letting you know that this got into the branch build.
Comment 53•23 years ago
|
||
Robert and Brian, Thanks for the getting this checked-in on very short notice. Masaki and/or Toshi, We do not have an environment internally to test this bug. We don't have ATOK X or VJE for Linux. Please test and mark this bug VERIFIED (assuming you can verify it). We can regress to make sure kinput2 still works. Also, please make sure the original bugzilla-j bug is updated, so folks in Japan know this has been fixed on the trunk.
Assignee | ||
Comment 54•23 years ago
|
||
I'm very sorry I found there is a theoretical error in nsWindow.cpp. > I verified the shell widget is always destroyed at last. My comment above is true for general widgets, however the order of destroying ICs is changed when the widgets have child widgets. IMEDestroyIC() is called from nsWindow::DestroyNative() at http://lxr.mozilla.org/mozilla/source/widget/src/gtk/nsWindow.cpp#304 But it's *before* DestroyNativeChildren() which would call nsWindow::DestroyNative() again. http://lxr.mozilla.org/mozilla/source/widget/src/gtk/nsWindow.cpp#309 That means IMEDestroyIC() is called for parent, then IMEDestroyIC() is called for child. The order is not valid. In that case, only mXIC of shell widget is destroyed and set to 0, mXIC of child widget is just a reference and not set to 0, so it may cause critical error. So, I had to change nsWindow.cpp with the patch. IMEDestroyIC() should be called after calling DestroyNativeChildren() from nsWindow::DestroyNative(). I sincerely appoligize for that. I'll attach an additional patch.
Assignee | ||
Comment 55•23 years ago
|
||
Comment 56•23 years ago
|
||
That looks reasonable to me. What is the behaviour when there is no shell widget that is managed by Mozilla? I'm specifically talking about an embedding context where the toplevel window is not a mozilla window. Use TestGtkEmbed as an example if you want to see.
Comment 57•23 years ago
|
||
The theory sounds reasonable to me, but if it is true, why didn't the build with the previous fix (2nd patch in this report) ever crash? My gut feeling is that we haven't really tested all this with enough variations yet. I'm somewhat uncomfortable about leaving it checked into the branch. Maybe we should consider backing it out. Or we could check in the new fix (3rd patch), but we've had even less soak time on that one. Reopening. Sorry.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Comment 58•23 years ago
|
||
Masaki (or anyone), Please create and try a testcase for your theory and see what actually happens?
Assignee | ||
Comment 59•23 years ago
|
||
When I put some debug message in IMEDestroyIC() as below, void nsWidget::IMEDestroyIC() { printf("IMEDestroyIC %x\n", this); if (!mXIC) return; printf("mXIC = %x\n", mXIC); if (mIsToplevel == PR_TRUE) { printf("delete mXIC %x\n", mXIC); delete mXIC; } else { // see discussion in bug 53989 printf("accessing mXIC %x\n", mXIC); nsWidget *widget = mXIC->GetFocusWidget(); if (widget && widget == this && mIMEShellWidget) { mXIC->SetFocusWidget(mIMEShellWidget); mXIC->UnsetFocusWidget(); } } mXIC = 0; } And I tried Search->Find In This Page and clicked Cancel button, which shows the following, IMEDestroyIC 862d178 mXIC = 86be988 delete mXIC 86be988 # mXIC is deleted here IMEDestroyIC 86a8058 mXIC = 86be988 accessing mXIC 86be988 # however, trying mXIC->GetFocusWidget() It is obviously an access error. I've verified this also happens at closing Preference Dialog. I've never seen any crash but it should be fixed. If I could run runtime checker of Sun's compiler (build fails with the compiler now...), it could notice the error easily. With the patch of nsWIndows.cpp, I've verified the order of destroying nsWidget is correct for all possible windows and dialogs of Mozilla, e.g. dialogs from Composer, Mail and Address Book. I'm seeing the irregular case in Bookmark Properties dialog that three popup windows (for menu) are destroyed after the shell widget is destroyed. However, it this case, I've also verified that popup window will be never focused. So it does not cause problem because mXIC will be never created.
Comment 60•23 years ago
|
||
per email from Erik, this fix will be backed out for RTM. Marking rtm-. Erik - pls note in this bug report when you have done that.
Whiteboard: [rtm++] [r=erik], sr=brendan → [rtm-] [r=erik], sr=brendan
Comment 61•23 years ago
|
||
I backed out the fix from the RTM branch.
Comment 62•23 years ago
|
||
For the trunk, I think we should consider keeping the patch, and applying the additional patch to make sure the objects are destroyed in the correct order. I will provide review comments for that patch shortly.
Comment 63•23 years ago
|
||
I agree and was just going to add that comment myself!
Comment 64•23 years ago
|
||
I had a look at the 3rd patch (11/04/00 01:35). I understand that calling IMEDestroyIC after calling DestroyNativeChildren will cause IMEDestroyIC to be called for the children before it is called for the top-level parent, and since they all share the same mXIC, we only delete that object when IMEDestroyIC is called for the top-level parent, but it seems like the code might still be a bit fragile even after this change. Since several objects are all pointing to one object, we need to be very careful about who is going to actually delete it, so that the other objects are not holding on to something that has already been deleted. In Mozilla, we often use normal ref-counting to make sure objects are not freed until there are no more objects referring to that one. Mozilla also has "weak references". Look for WeakReference. Are we sure that all child objects will always be destroyed before a top-level parent is destroyed? For example, what if we re-parent a child or group of children? Or, if we are not doing that now, what if we do that in the future?
Comment 65•23 years ago
|
||
If this is really the case I would suggest that the object be cached at the toplevel window. This way, no child window will ever have a stale reference and there won't be any of these kinds of race conditions. Is there a chance that this could be a singleton object? Does more than one of these exist for the entire application?
Comment 66•23 years ago
|
||
It is my understanding that mXIC is a wrapper around GdkIC, which is itself a wrapper around XIC. You can only associate one "client" window with an XIC, and it may not be changed. Apps generally have one XIC per top-level window or one XIC per widget inside a top-level window. For Mozilla, the Sun folks have implemented one IC per top-level window. In the embedding case, Mozilla may be embedded inside an app that does not use nsWidgets. In this case, we may wish to cache the mXIC at the highest nsWidget. The child widgets could access the IC by calling a method that goes up the hierarchy to the top nsWidget. Or each child could store its own pointer to the IC, but it should then be ref-counted for safety. I'd be happy to go either way on this. Comments? Blizzard? Katakai?
Assignee | ||
Comment 67•23 years ago
|
||
Thanks for comment, Erik. Yes, we can use the highest widget as the shell widget to control XIC. Chris has suggested GetMozArea() to retrieve the widget. I attached the patch in http://bugzilla.mozilla.org/show_bug.cgi?id=50130 and it works in both Mozilla and GtkEmbed.
Comment 68•23 years ago
|
||
OK, but the patch in bug 50130 does not address the fact that all widgets have a pointer to a single top-level mXIC object, which is dangerous, as we have seen. At the very least, we need to apply the 3rd patch in this report (11/04/00 01:35) to destroy objects in the right order. We may wish to have an additional patch that either stores the mXIC in *one* place (highest widget) and has the children fetch that pointer by climbing the hierarchy, or changes mXIC to a ref-counted object (e.g. XPCOM object that implements nsISupports). Perhaps there is no need to go for the ref-counting method, so how about climbing the hierarchy. For example (pseudo-code): nsXIC nsWidget::GetInputContext(void) { nsWidget* parent = GetParent(); if (parent) { return parent->GetInputContext(); } else { return mXIC; } }
Assignee | ||
Comment 69•23 years ago
|
||
Erik, Thanks for suggestion. Yes, we should store XIC in one place. However, I remember that getParent() of nsWidget method can not be used to retrieve the highest widget so we made the current GetShellWidget() codes. I don't think the current GetShellWidget() codes and new codes of using GetMozArea() work properly when the highest widget is destroyed before child. Can we use hashtable to store ShellWidget and XIC pair? We can store XIC value in the hashtable and retrieve by ShellWidget key. Even when shell widget is destroyed before child irregularly, we can prevent the access error. nsIMEGtkIC* nsWidget::GetInputContext() { if (mIMEShellWidget) { return (nsIMEGtkIC*) g_hash_table_lookup(mXICLookupTable, mIMEShellWidget); } return nsnull; } void nsWidget::IMEDestroyIC() { nsIMEGtkIC *xic = GetInputContext(); // we can prevent bad access (xic->GetFocusWidget()) when // mIMEShellWidget is destroyed before if (!xic) return; if (mIsToplevel == PR_TRUE) { // remove XIC from hashtable by mIMEShellWidget key g_hash_table_remove(mXICLookupTable, mIMEShellWidget); delete xic; } else { // see discussion in bug 53989 nsWidget *widget = xic->GetFocusWidget(); if (widget && widget == this && mIMEShellWidget) { xic->SetFocusWidget(mIMEShellWidget); xic->UnsetFocusWidget(); } } }
Assignee | ||
Comment 70•23 years ago
|
||
I got a report that the original submitter has verfied XIM works without any errors on the latest build on Debian and FreeBSD. http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=285
Comment 71•23 years ago
|
||
Maybe I'm misunderstanding, but that suggestion seems very strange to me. When would a widget be destroyed before one of its children? Should that ever happen? Also, your hash table is called mXICLookupTable, implying that it is a member of nsWidget. Does this mean that each widget contains such a hash table? Or would the hash table be global? If so, how can we tell whether an entry in the hash table refers to a valid shell widget? I don't like this idea at all. I'd rather solve the "parent dying before child" problem (if there is such a problem).
Assignee | ||
Comment 72•23 years ago
|
||
I'm also misunderstanding, sorry. I was thinking you concerned about the irregular case. Yes, I never seen such case when I tried possible window and dialog. So, the exact problems are, - each nsWidget has a reference of mXIC - each nsWidget has a reference of mIMEShellWidget and we should try to store mXIC into one place, right? How about the following scenario? - Child nsWidget does not have a reference of mIMEShellWidget. When nsWidget wants to acess the shell widget, call nsWindow::GetMozArea() for each time - Child nsWidget does not have a reference of mXIC. To get mXIC, get shell widget first by above, then return widget->mXIC if exists To store mXIC, get shell widget first by above, then store as shhe widget->mXIC However, GetMozArea() has a cache of the widget, which means we will still have a reference of IMEShellWidget. Is this a problem? We will never meet the irregular case, so can we trust IMEShellWidget is always valid? Or should we use another GetMozArea() which doesn't have a cache? But it would cause performance regression because gdk_window_get_parent() is repeated every time.
Comment 73•23 years ago
|
||
It seems like it's OK to assume that the child widgets are destroyed before the parent widget, right? If so, GetMozArea can cache the shell widget, and it should be OK.
Comment 74•23 years ago
|
||
Erik, don't make the assumption that widgets are destroyed top down in all cases. In the case where it's embedded top toplevel window ( not the mozarea ) will be destroyed before the child widgets are and there's a good chance that the native underlying windows will be destroyed as well. This means that you have to make sure that you remove all of the native references in a way that it can handle either case - top down or bottom up.
Assignee | ||
Comment 75•23 years ago
|
||
The shell widget is passed to XCreateIC() as client_window at XIC creation. The window should be valid while the XIC is being used. So, from XIM point of view, in either case, top down or bottom up, the mXIC should be destroyed when the shell widget is destroyed. So, how about using hashtable again? We need to have a way to check shellwidget is valid or not at destroying. I understand we can not use the reference of shellwidget at creation, also can not use GetMozArea() at that time. If we could manage a shellwidget - XIC pair in hashtable, we can remove the entry at destruction so that we can check the shellwidget is valid or not. (nsWidget will still have a reference of shellwidget, but will not use it if no entry is in the hashtable) I think using hashtable is reasonable solution. - hashtable is global - when XIC is created, insert the XIC with shellwidget key to hashtable - each nsWidget has a reference of the shellwidget - each nsWidget can retrieve XIC from the hashtable with shellwidget key - when shellwidget is destroyed, remove XIC from hashtable - after shellwidget is destroyed, no entry in hashtable for XIC child widget has a reference of shellwidget, but does not understand it's valid or not. child widget can know the shellwidget is valid by checking the hashtable. If entry is in hashtable, it means the shellwidget is valid, also XIC is valid. If not, the reference of shellwidget can not be used, which means XIC is already destroyed. I'll attach temp patch.
Assignee | ||
Comment 76•23 years ago
|
||
Comment 77•23 years ago
|
||
I don't know enough about widgets and their hierarchies to say whether the hash table approach is the best design. Chris, what do you think?
Comment 78•23 years ago
|
||
Updated Status Whiteboard and removed "[r=erik], sr=brendan", since we are working on a new patch.
Whiteboard: [rtm-] [r=erik], sr=brendan → [rtm-]
Assignee | ||
Comment 79•23 years ago
|
||
Chris, any comments on the patch of http://bugzilla.mozilla.org/showattachment.cgi?attach_id=19148 ? This also can solve the embeded problem, bug 50130.
Updated•23 years ago
|
Updated•23 years ago
|
Assignee | ||
Comment 82•23 years ago
|
||
Assignee | ||
Comment 83•23 years ago
|
||
I updated the patch. This also can solve bug 50130 (gtkembed problem), - use hashtable to manage xic - proper way to get shell widget (see bug 50130) - correct destroying order
Comment 84•23 years ago
|
||
I'll review this soon but I'm in the process of moving. It will be a few days.
Comment 85•23 years ago
|
||
Katakai-san, It seems that with this code that there is a lot of room for improvement. For example, there are a few different ways to get an Input Context: nsIMEGtkIC *xic = IMEGetInputContext(); xic = nsIMEGtkIC::GetXIC(mIMEShellWidget, gPreeditFontset, Can't we move that all to a single method with one way to get the XIC? I also see this code: nsIMEGtkIC *xic = IMEGetInputContext(); if (!xic) { GetXIC(); } xic = IMEGetInputContext(); Which says "get the XIC, if it failed do initialization via GetXIC() and reget the XIC." Can't you move that implicit initialization into IMEGetInputContext() and remove the check? There might be other places where this isn't done and that check isn't made. Might that cause problems? You also might want to use the mozilla hash table or an nsVoidArray which I'm pretty sure is a hash table underneath. In my humble opinion it's much more readable. Are there any cases where we are doing XIM pre-edit over anything that is not a native Mozilla window? That is, is this something that can be moved into the nsWindow class? We are doing some bad casting here back and forth and it gives me the willies.
Comment 86•23 years ago
|
||
brendan informs me that the void array isn't a hash table and he's right. You should probably use the has table implementation in xpcom if possible.
Comment 87•23 years ago
|
||
Some comments that I hope are helpful: You can make mXICLookupTable be statically allocated, not just a static pointer to a dynamically allocated glibc hash table. BTW, you should use the 'g' rather than 'm' prefix for such static "globals": gXICLookupTable. Last time I checked, glib hash tables used chaining, so were malloc-intensive, and used a division hash. xpcom/ds/pldhash.[ch] uses double hashing (one malloc for the all entries in the table) and multiplicative hashing (which beats division hash in cycles and effectiveness in spreading keys to avoid collisions). While you could use xpcom/ds/nsHashtable.h, until the fix for bug 72722 goes in, that incurs lots of malloc overhead, not only per entry but per entry key! If you can tolerate the complexity, pldhash.h usage wins on memory, minimizing malloc overhead on all fronts. Here is a sketch, showing the glibc hash table code in comments, followed by the pldhash alternative: #include "pldhash.h" struct nsXICLookupEntry : public PLDHashEntry { nsWidget* mWidget; nsIMEGtkIC* mXIC; }; //GHashTable *nsWidget::mXICLookupTable = NULL; PLDHashTable nsWidget::gXICLookupTable; //if (mXICLookupTable == NULL) { // mXICLookupTable = g_hash_table_new(g_direct_hash, g_direct_equal); //} //XXX we don't check for out-of-memory errors here, in either version. if (gXICLookupTable.ops == NULL) { PL_DHashTableInit(&gXICLookupTable, JS_DHashGetStubOps(), NULL, sizeof(nsXICLookupEntry), 16)) } // g_hash_table_insert(mXICLookupTable, mIMEShellWidget, xic); nsXICLookupEntry* entry = NS_STATIC_CAST(nsXICLookupEntry*, PL_DHashTableOperate(&gXICLookupTable, mIMEShellWidget, JS_DHASH_ADD)); if (entry) { entry->mWidget = gIMEShellWidget; entry->mXIC = xic; } // return (nsIMEGtkIC*) g_hash_table_lookup(mXICLookupTable, mIMEShellWidget); nsXICLookupEntry* entry = NS_STATIC_CAST(nsXICLookupEntry*, PL_DHashTableOperate(&gXICLookupTable, mIMEShellWidget, PL_DHASH_LOOKUP)); return entry->mXIC; // g_hash_table_remove(mXICLookupTable, mIMEShellWidget); PL_DHashTableOperate(&gXICLookupTable, mIMEShellWidget, PL_DHASH_REMOVE); Where should the hash table be destroyed? It appears to be leaked in the patch. /be
Assignee | ||
Comment 88•23 years ago
|
||
Thank you very much for comments, Chris and Brendan. I'll post new patch if ready. The reason why I used GHashTable is I found the hashtable is used in nsWindows.cpp. Should we file new bug and try to fix this as well? // this is a hash table that contains a list of the // shell_window -> nsWindow * lookups GHashTable *nsWindow::mWindowLookupTable = NULL;
Comment 89•23 years ago
|
||
The hash table that's in nsWindow.cpp is my code and I probably should have used the correct hash table when I did it. I'm not that worried about fixing the code that is in there right now but I am worried about making sure that the pattern isn't replicated if possible.
Comment 90•22 years ago
|
||
*** Bug 71796 has been marked as a duplicate of this bug. ***
Assignee | ||
Comment 91•22 years ago
|
||
Thanks for comments, Chris and Brendan, I've updated my patch, sorry for late, please review. - Use PLDHashTable instead of GHashTable - Most XIM codes have been moved to nsWindows from nsWidget - XIC is retrieved by IMEGetInputContext() and is only created by IMEGetInputContext() when it's called from IMESetFocusWindow(), which is being used as a trigger to create XIC - mIMEShellWindow is also retrieved only in IMESetFocusWindow() - removed unnecessary retrieving XIC, for example, a() { nsIMEGtkIC *xic=IMEGetInputContext(); b(); } b() { nsIMEGtkIC *xic=IMEGetInputContext(); ... } has been changed to the following if possible case, a() { nsIMEGtkIC *xic=IMEGetInputContext(); b(xic); } b(nsIMEGtkIC *xic) { ... } And I've verified the following with the new patch, - verified no errors and warnings with gcc, with -DUSE_XIM without -DUSE_XIM - verified japanese input works on Linux and Solaris - verified the original bug does not happen on Linux with ATOKX - verified japanese input works on gtkEmebed on Linux and Solaris, on both on-the-spot and over-the-spot mode (with patch of bug 66951, but I found focus problem on gtkEmebed on nightly. see bug 76617) But, I didn't put deletion codes of the hash table. Chris, do you have idea about the deletion point ?
Assignee | ||
Comment 92•22 years ago
|
||
Comment 93•22 years ago
|
||
Since, this is P3 | Critical, and it looks like we may have a patch, can we get this in for nsbeta1? Please assign for M0.9.1
Assignee | ||
Comment 94•22 years ago
|
||
Updated the patch for today's nightly. (some updates in nsWidget.cpp and nsWindow.cpp). Please review.
Assignee | ||
Comment 95•22 years ago
|
||
Comment 96•22 years ago
|
||
You should change this code: + GtkWidget *top_mozarea = aWindow->GetMozArea(); + if (top_mozarea) { + mozAreaWindow = (nsWindow *)gtk_object_get_data(GTK_OBJECT(top_mozarea), "n sWindow"); + } to use NS_STATIC_CAST() like so: mozAreaWindow = NS_STATIC_CAST(nsWindow *, gtk_object_get_data(GTK_OBJECT(top_mozarea), "nsWindow")); That's the pattern we use other places. @@ -723,14 +609,11 @@ /* virtual */ void nsWidget::LoseFocus(void) { +exit(1); // doesn't do anything. needed for nsWindow housekeeping, really. if (mHasFocus == PR_FALSE) return; You probably want to remove that exit(1) in there. :) Why are nsWidget::IMEComposeStart(), IMECommitEvent(), and IMEComposeText() still included if they aren't called and are just assertions? Are there other dependencies that I don't see? If they are truly unused, please remove them. +struct nsXICLookupEntry : public PLDHashEntryHdr { + nsWindow* mShellWindow; + nsIMEGtkIC* mXIC; +}; This is a valid C+ but it's kind of clunky to me. Since you are using a struct can you use: struct nsXICLookupEntry { PLDHashEntryHdr keyHash; nsWindow *mShellWindow; nsIMEGtkIC *mXIC; }; When I looked at the PLD hash table header file I was kind of confused by this because of the use of public: instead of just putting it in the structure. +/* virtual */ void +nsWindow::LoseFocus(void) +{ + // doesn't do anything. needed for nsWindow housekeeping, really. + if (mHasFocus == PR_FALSE) + return; + +#ifdef USE_XIM + IMEUnsetFocusWindow(); +#endif // USE_XIM + + sFocusWindow = 0; + mHasFocus = PR_FALSE; + +} You should move the sFocusWindow = 0 and the mHasFocus related code back down to nsWidget if possible in case it ends up getting used from there again. In nsWindow::IMEGetShellWindow(void) you have another old style case that should be an NS_STATIC_CAST(). + textEvent.widget = (nsWidget *)this; Another old style cast. There are a few of those that you should fix. Other than that the patch looks OK to me. Let me do some testing.
Comment 97•22 years ago
|
||
The patch doesn't seem to cause any problems that I can see. r/sr=blizzard
Assignee | ||
Comment 98•22 years ago
|
||
Thank you very much for comments. I have fixed the codes except LoseFocus(). I'm sorry I don't have good idea for LoseFocus(). Do you have? I'll attach the diffs from the *previous* patch just for quick reference. - fixed old style cast - removed exit() - change to the following for nsXICLookupEntry, struct nsXICLookupEntry { PLDHashEntryHdr mKeyHash; nsWindow* mShellWindow; nsIMEGtkIC* mXIC; }; - removed Unnecessary virtual functions from nsWidget only IMECommitEvent() is needed I'll commit the changes after testing is completed on Linux. Thank you very much for review.
Assignee | ||
Comment 99•22 years ago
|
||
Assignee | ||
Comment 101•22 years ago
|
||
change status to FIXED
Status: NEW → RESOLVED
Closed: 23 years ago → 22 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 102•22 years ago
|
||
marked this as verified. Mozilla with ATOK12 works fine also I've never heard such problem from users.
Status: RESOLVED → VERIFIED
Updated•13 years ago
|
Keywords: inputmethod
You need to log in
before you can comment on or make changes to this bug.
Description
•