Community
Participate
Working Groups
I propose to include here only general solutions.
Created attachment 5637 [details] OS.java from build N20030729 with proposed changes. Our changes are marked with tag "bidi"
Created attachment 5638 [details] File os.c from build N20030729 with proposed changes
Created attachment 5639 [details] Display.java from build N20030729
Created attachment 5640 [details] Shell.java from build N20030729
Created attachment 5641 [details] Widget.java from build N20030729
Created attachment 5642 [details] Dialog.java from build N20030720
Created attachment 5643 [details] MenuItem.java from build N20030729
Created attachment 5644 [details] ToolItem.java from build N20030729
From our point oview, first changes should be done in the following files: Display: Allows setting of default text direction in accordance with orientation of first top Shell. I think, it is better, that simply set default direction as LTR in the method init(), because such standard GTK modules, as FileDialog or FontDialog, create in the process of their work internal message boxes, that are not accessible from SWT and therefore orientation of them can't be changed. It will help us to solve, as minimum, problem of orientation of dialogs, that inherit their orientation from top Shell. Shell: Allows to the top Shell set default orientation in accordance with it's orientation's style. Widget: Set orientation of corresponding GTK widgets (using recursive method) after creating of the "handle" of SWT widget. This will simplify process of orientation's setting and will help us to set correct orientation of internal GTK widgets, which are not created directly by SWT. MenuItem, ToolItem: Call method Widget.checkOrientation() with purpose to inherit orientation style from their parents. Dialog: Set orientation of dialog using new recursive method
Created attachment 5669 [details] Scrollable.java from build N20030729 We can solve here problem with position of vertical scroll bar for all rtl-oriented children of Scrollable.
I'm a bit confused here Semion. I thought that we would implement for GTK the -same- support we have on Windows and I see in this code new public API like Widget.setWidgetOrientation and Dialog.setDialogOrientation. These API does not exist on Windows so why did you added them to GTK ? I guess these API are just for testing (prototype) and are not meant to be released. Am I right ? SWT has to have exactly the same API in all the platforms. Since this is our "start" point I expect to see here a GTK implementation of the basic framework we developed for Windows. This would include changes in methods such: Widget.checkOrientation (); // already in place Control.createWidget (); // already in place Control.createHandle (); // implement equivalent (Note, places like Widget.checkOrientation where we can have exactly the same code in windows and GTK are great). (Note, I don't consider Widget.setWidgetOrientation a equivalent of Control.createHandle cause it is a public API). This would give us the basic support to honour the flag SWT.RIGHT_TO_LEFT, and inherit parent's orientation. Change the subject, I don't think we should release the code for Dialog, in the first place Dialog in a common code (run in all the platforms) therefore it can not contain GTK specific code. The code is also hacky, it works based on probability, it assumes that if the first Shell is RTL all others Dialog for that Display will also be RTL. I know GTK dialogs use stock items and the first time a dialog is initialized it also initialize the items on stock using the current default orientation. Later if another dialog with different orientation is create it reuses the stock items causing the problem. Is that right ? I know that we can force the Dialog to not use the stock items, but maybe we also could provide a different stock items or maybe flush (forcing the items to be recreate) the stock when the orientation changes. I'm also check the code for 41188, 41201, 41202 and I can release them all, but first I would like to have this problem fixed. To move on more quickly we should: a) get rid of the public APIs b) ignore the problem with the Dialog for now
If you guys catch up the SWT code today you will see that Steve and I have released code in Widget, Button, and Scrollable. In Widget and added a method named setOrientation (), this method is called from Widget.createWidget() just after the createHandle() and this new method is where we should place all the code responsible by setting the widget orientation. Button and Scrollable are examples of an implementation of setOrientation(). Instead of keep Widget.setWidgetOrientation which loops thru the whole hierarchy and change every single handle we opted by setting orientation just for leaf widgets. We now need to do for all widgets what we did for Button, reimplementing setOrientation(). Note that some widget will need to call super.setOrientation () for example subclasses of Scrollable.
Felipe, two methods, that you wrote about in the comment #11, aren't supposed to be an API methods. Method setDialogOrientation() is private; method setWidgetOrientation() has public access, but only in purpose to be called (in the future, for dynamic changing of orientation) from other SWT package (some examples of this can be found in the SWT code). Currently we can decrease it's access to private, if it is better from your point of view. Any way both methods are planed to work as internal, private methods. As your setOrientation(), setWidgetOrientation() should be called (currently) only once from method createWidget() after method createHandle(). It loops thru the whole hierarchy of GTK container, which correspond to current SWT widget, therefore it can set text direction of all GTK widgets in this hierarchy, including such widgets, that aren't accessible from SWT. Using this method, we can forget about specifics of SWT widget and receive result, which is maximum closed to native (it means, when SWT widget is created with corresponding default text direction property). Unlike it, your method setOrientation() works only with SWT specific widgets, therefore it looks as unnecessary method, because it doesn't contain common code. In all cases code from this method can be included in the code of createHandle() of current SWT widget. Regarding Scrollable, code , which is common for all it's subclasses, should be included (from my point of view) to the createWidget(), as it is already done for creating of scrollbars. Regarding standard dialogs, I don't think, that using of stock items has any relationship with problem of dialog's orientation. As in other cases, when we create current standard dialogs, GTK create hierarchy of corresponding widgets, and behavior of these widgets depend on default or current widget's text direction. Using setDialogOrientation(), we can set corresponding text direction for all widgets in this hierarchy. Problem here is that some standard dialogs, as FileDialog or DirectoryDialog, in the process of their work use some additional internal dialogs, which currently aren't accessible from SWT in the time of dialog's creating. Therefore behavior of these internal dialogs depend on default text direction only. In addition we should check, if we can receive access to these dialogs using GtkFileSelection structure. In all cases I think, that setting of default text direction in accordance with orientation of first top Shell isn't bad idea... I didn't know, that code of Dialog is used for all platforms and therefore it can't contain platform specific code. If it is necessary, we can create it's intermediate GTK specific subclass like GtkDialog.
If the problem with the Dialgos is that the whole hierarquy is not create by the time you loop thru the children maybe realizing the top handle of the Dialog will force all the children to be create created.
Semion, 1) You absolutely cannot add public methods on one platform that are not available on the other. The only exception to this rule are methods that are prefixed by the platform code such as win32_new. 2) Code that loops through a hierarchy of handles, hammering a property for every handle it finds is generarlly problematic and source of future problems. Please use the methods Felipe has provided that explictly change the necessary handled unless there is some reason you cannot. 3) Any hack such as using the orientation of the first shell that is created to determine something needs to be discussed with the members of the SWT team. If Felipe were to add such a method, he would ensure that someone else on the team knew what he was doing and why. Otherwise, SWT becomes unmaintainable.
Felipe, as far as I understand, internal dialogs, that we wrote about, are created after corresponding option's button is pressed and are destroyed in the end of working with them. Probably, we can't receive access to these widgets from SWT.
Steve, problem with public methods is understood. As I wrote in the previous comment, both proposed methods aren't planned to be part of API and should be used as private methods only. I don't understand, why do you think, that code, which loops through hierarchy of handles and changes their direction property, is problematic and what problems can be caused by using of it. Can you give me any example to explain this? Currently I see only advantages of this suggestion and I hope, that you will change your decision. Using orientation of first shell to determine default orientation isn't very differ from simple setting of default orientation to LTR, but it has, from my point of view, more sense. Once more, it is only one of our suggestions: I see (and can explain) reason, why we need to use it and I currently don't see reason, why we can't. Final decision belongs to OTI...
Semion, In comment #13 you said that looping thru the hierarchy also change the orientation of internal widgets, which are not accessible from SWT code. Would you have a specific example (other than dialogs) where the orientation of a internal widget has to be change and the only way to reach this widget is looping thru the hierarchy ?
Felipe, here we have problem with terminology (it is my fault). It isn't correct to say, that GTK widget is not accessible from SWT, if some method can, for example, change some of widget's properties. Moreover, SWT itself creates for each SWT widget specific hierarchy of GTK widgets, therefore each entry from this hierarchy is accessible - and in spite of this it can be one of widgets, that I have in mind. Let us say, that method, which "loop through", simplify our access to all widgets including such of them, that aren't used directly by SWT. For example, ToolItem with DROP_DOWN style contains two GtkHBoxes: first of them contains arrow and second hbox; second hbox, in it's turn, contains label and image. Label and image are used by SWT directly for corresponding settings, but two above-mentioned hboxes aren't used after creating of ToolItem. Till now first of them was not leaf widget, but direction of it should be changed as well. One more example - MenuItem. As far as I understand, only GTK menu item in this case can be determined as leaf widget. It is not enough. Without method, that loop through this hierarchy, we can't achieve suitable result. Note, that text direction isn't the only property, than can be changed in the time of loop. Another example - position of vertical scrollbar of GtkScrolledWindow. We only should start our loop not from handle, but from fixedHandle and use the code, example of which can be found in the proposed setDialogOrientation() method. As result we can remove code, that was written especially for Scrollable (and receive correct position of scrollbar for all it's children), and in addition achieve our purpose with "not accessible" widgets, like scrolled window of GtkCombo's drop-down list. Finally, from my point of view it is better to use one ( and only one) low level method then add to each SWT widget it's specific method, which handle list (in some cases, long list) of it's specific leaf widgets. In many cases setting of direction property isn't enough and we should write some additional widget specific code. This code can be placed in the separate method, but I think, that createHandle() is the best place for it.
FYI: In the GTK bugzilla you can find: 76219 Complete the RTL flipping support (http://bugzilla.gnome.org/show_bug.cgi?id=76219) Which has a list of GTK bidi bugs that is interesting for our work.
Now, when release GTK 2.3.2, which includes many bidi-related fixes, is already available, I would like to continue our work with base SWT widgets on GTK platform. Before interruption we discussed two ways of setting their orientation: 1) set orientation only of some important GTK widgets, which are used by current SWT widget; 2) set (in loop) orientation of all GTK widgets, which put together current SWT widget. I still prefer second solution, but now suggest to use function gtk_container_forall() with callback from SWT. First of all - about reason of this approach. SWT widget is almost always based on GTK container with some internal GTK widgets inside. Some of these widgets are created and added to corresponding container by SWT. Sometimes setting orientation of these widgets is enough to achieve suitable behavior of SWT widget, but not always. Dialogs are example, when we need the deep loop for orientation's setting. Even in cases, when we have direct access to all GTK widgets, which have influence on final look of SWT widget, the second solution looks better, because it is more simple, less widget specific and therefore it, in general case, doesn't depend on current widget realization in GTK. This solution is pure native and need additions from SWT side only in cases, when specific SWT widget is released by some "not pure native" or "not standard" way. For example, SWT Group, which is based on GtkFrame, need additional setting direction of its label, because this label (which is created by SWT within createHandle() method) isn't added to GtkFrame immediately after container's creating, but only within setText() method. Note, that suggested solution doesn't mix SWT and GTK widgets and uses only GTK widgets' tree. The similar solution is used by GTK for changing the application's default text direction ( as result, direction of all widgets, which don't have explicitly assigned orientation, is dynamically changed). We have some advantages in using gtk_container_forall() instead of gtk_container_get_children() from previous suggestion: 1) We shouldn't work with internal elements of a toolkit from SWT; 2) gtk_container_forall() is released for all GTK containers and takes into consideration the specifics of each of them; 3) Using of gtk_container_forall() is more simple and need less changes in SWT code. In addition I suggest to open separate bugs for toolbars, menus and dialogs.
Created attachment 7781 [details] os.c from build I20040210 with proposed changes Our canges have tag b41184.
Created attachment 7782 [details] OS.java from build I20040210 with proposed changes
Created attachment 7783 [details] Display.java from build I20040210 with proposed changes
Created attachment 7784 [details] Widget.java from build I20040210 with proposed changes
Created attachment 7785 [details] Scrollable.java from build I20040210 with proposed changes
Starting with GTK 2.3.2, problem with position of vertical scroll bar is solved. Therefore file Scrollable.java shoud be updated.
Fixed in HEAD > 20050225 I kept the setOrientation framework, I'm not using container_forall in all the cases, I believe each place where I need to use container_forall represents a bug in GTK. Right now I using it for dialogs, menu items and table columns.