Community
Participate
Working Groups
Created attachment 89170 [details] Screen shot under Linux showing layout and size bugs
Snippet description: The snippet opens a shell with a single child composite and then calls a test function 3 times with 3 different sample strings. The test function uses a Form layout manager to stack a label (for displaying size information about the following Text control), a Text control, another label (for displaying size information about the following Combo control) and then another Combo control. Both the Text and Combo controls are initialized with the passed in sample string and then the computeSize() method is called to see how long they should be. The returned size information is then passed in to the computeTrim() method to see how much room the trim will take. The results of the method calls are them displayed in the controls corresponding labels. For the last call to the test function the Combo control has it's width set to the calculated width from the Text control. The snippet demonstrates the following bugs: 1 – On Linux the combo returns an invalid preferred width regardless of the string the Combo is initialized with. As a matter of fact it appears that the Combo returns the same preferred size regardless of what string it is initialized with. If you run this under Windows the preferred size does appear to change with the string size although Windows also returns the wrong size because of another bug described below. 2 – On both Windows and Linux the Combo.computeTrim() method returns a rectangle the is the exact same as the client rectangle that is passed in. The same calls on the Text control works fine under both platforms. 3 – On Windows the Combo's returned preferred size appears to return the proper size of the text plus the size of the drop down button. On 4 – If setting the width of a control is supposed to set the client width then setting the width of a Combo under Linux is broken, If setting the width of a control is supposed to set the outside bounds of the control then setting the width of a Combo is broken on both Windows and Linux. If you run the test snippet on Windows (at the bottom) you will see that setting the width of a Combo on Windows sets the client area to be the same size as the text control's client area. Under Linux, when running the test snippet, setting the width of the Combo doesn't match either the Text controls client width or its outside bounds. -------------------------------------------------- Here is a snippet which demonstrates the issues -------------------------------------------------- import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.*; public class ComboLayoutBugs { private static Combo lastCtrl = null; public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); Composite comp = new Composite(shell, SWT.NONE); test (comp, "Example String", false); test (comp, "X", false); test (comp, "Width Test", true); shell.setSize(600, 400); shell.layout(); shell.open (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); } public static void test (Composite parent, String testString, boolean lastCall) { int textCtrlWidth; // Set the composite to use the form layout manager FormLayout mainPnlL = new FormLayout(); mainPnlL.marginWidth = 5; mainPnlL.marginHeight = 5; mainPnlL.spacing = 5; parent.setLayout(mainPnlL); parent.setBackground(new Color(null, 255, 255, 255)); // Create a label to show size information above the test Text control Label tlCtrl = new Label (parent, SWT.NONE); FormData fd = new FormData(); fd.left = new FormAttachment(0); // Make the first control follow the last control laid out if necessary if (lastCtrl == null) fd.top = new FormAttachment(0); else fd.top = new FormAttachment(lastCtrl, 0, SWT.BOTTOM); fd.right = new FormAttachment(100); tlCtrl.setLayoutData(fd); // Create the test Text control and position it below the label from above Text txtCtrl = new Text (parent, SWT.BORDER); txtCtrl.setText(testString); Point p = txtCtrl.computeSize(SWT.DEFAULT, SWT.DEFAULT); Rectangle r = txtCtrl.computeTrim(0, 0, p.x, p.y); FormData tfd = new FormData(); tfd.left = new FormAttachment(0); tfd.top = new FormAttachment(tlCtrl, 0, SWT.BOTTOM); tfd.width = p.x; textCtrlWidth = p.x; txtCtrl.setLayoutData(tfd); // Display the size information for the Text control tlCtrl.setText("Preferred Size: " + String.valueOf(p.x) + "x" + String.valueOf(p.y) + " Trim Sizes: " + "Left=" + String.valueOf(r.x * -1) + ", Top=" + String.valueOf(r.y * -1) + ", Right=" + String.valueOf(r.width - (p.x - r.x)) + ", Bottom=" + String.valueOf(r.height - (p.y - r.y))); // Create a label to show size information above the test Combo control Label clCtrl = new Label (parent, SWT.NONE); fd = new FormData(); fd.left = new FormAttachment(0); fd.top = new FormAttachment(txtCtrl, 0, SWT.BOTTOM); fd.right = new FormAttachment(100); clCtrl.setLayoutData(fd); // Create the test Text control and position it below the label from above Combo cmbCtrl = new Combo (parent, SWT.BORDER); cmbCtrl.setText(testString); p = cmbCtrl.computeSize(SWT.DEFAULT, SWT.DEFAULT); r = cmbCtrl.computeTrim(0, 0, p.x, p.y); FormData cfd = new FormData(); cfd.left = new FormAttachment(0); cfd.top = new FormAttachment(clCtrl, 0, SWT.BOTTOM); // For the last example we try to make the combo the same width as the text control if (lastCall) cfd.width = textCtrlWidth; else cfd.width = p.x; cmbCtrl.setLayoutData(cfd); // Display the size information for the Text control clCtrl.setText("Preferred Size: " + String.valueOf(p.x) + "x" + String.valueOf(p.y) + " Trim Sizes: " + "Left=" + String.valueOf(r.x * -1) + ", Top=" + String.valueOf(r.y * -1) + ", Right=" + String.valueOf(r.width - (p.x - r.x)) + ", Bottom=" + String.valueOf(r.height - (p.y - r.y))); // Remember the last control created so we can layout more after it lastCtrl = cmbCtrl; } }
Just looking at the screen shot, I don't see the bugs ... but I'm tired and I will run the code.
#1 is a bug, and we're investigating. #2 can't do anything #3 is there info missing here? #4 Setting the width is supposed to set the bounds. See snippet: package bog.javasnippets; import org.eclipse.swt.*; import org.eclipse.swt.widgets.*; public class PR218224 { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); Combo combo = new Combo(shell, SWT.NONE); combo.pack(); combo.setSize(100, combo.getSize().y); System.out.println("Combo " + combo.getSize()); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
I'm curious as to why there is nothing that can be done on #2. It appears to work properly for the Text control but doesn't work for a Combo control on either Windows and Linux and it can't be fixed? My comment on #3 was that if you run the snippet on Windows and look at the values returned from computeSize() for a Text control, it appears to return a size that fits the text. If you call computeSize() for the Combo control (under Windows) it appears that the returned size is inappropriate for the text as it (incorrectly) includes an additional amount equal to the width of the combo's drop down button. Regardless, if you get the preferred width of a Combo via a call to computeSize() and then set the width of the control to that width, there shouldn't be a bunch of extra unused client space left over, or at least no more than the Text control which appears to work properly on both platforms. That was all that I was trying to say for #4.
I am also experiencing #1. On Linux the preferred size of the Combo is much larger than on other platforms. In my case all items in the combo have 2 characters and I expect the combo to be big enough to accommodate that. However when the SWT.READ_ONLY flag is used the preferred size is good. Right now I have to implement my own preferred size calculation on Linux to compensate for this bug.
I can still reproduce #1 on Fedora 29 using SWT master. With SWT.READ_ONLY, the preferred size is good.
Not sure if we can do much about the preferred size for non-SWT.READ_ONLY Combos. The size is calculated internally and it appears GTK behaves this way natively as well.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.