diff options
| author | Thomas Fitzsimmons <fitzsim@redhat.com> | 2005-08-18 01:21:59 +0000 |
|---|---|---|
| committer | Thomas Fitzsimmons <fitzsim@redhat.com> | 2005-08-18 01:21:59 +0000 |
| commit | e9438334943449d2941b4da0f8a402ca73a27437 (patch) | |
| tree | 2a53853f1908e5f444961fe865df2fbdc059702b /gnu/java | |
| parent | a65d9284f44e5a09ff254a9b5af59d848a6b3b76 (diff) | |
| download | classpath-e9438334943449d2941b4da0f8a402ca73a27437.tar.gz | |
2005-08-17 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkFramePeer.java,
gnu_java_awt_peer_gtk_GtkFramePeer.c (postConfigureEvent): Prevent
callback calling back into peers.
(setBounds): Likewise.
(setMenuBarWidthUnlocked): New method.
* native/jni/gtk-peer/gtkpeer.h (cp_gtk_filedialog_init_jni):
Declare function.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
(gtkInit): Call cp_gtk_filedialog_init_jni.
(loadSystemColors): Work around deadlock.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
(textcomponent_changed_cb): Don't release GDK lock.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
(item_activate_cb): Don't release GDK lock.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
(item_highlighted_cb): Don't release GDK lock.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
(component_button_press_cb): Don't release GDK lock.
(component_button_release_cb): Likewise.
(component_motion_notify_cb): Likewise.
(component_enter_notify_cb): Likewise.
(component_leave_notify_cb): Likewise.
(component_expose_cb): Likewise.
(component_focus_in_cb): Likewise.
(component_focus_out_cb): Likewise.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
(block_expose_event_cb): Remove callback.
* gnu/java/awt/peer/gtk/GtkWindowPeer.java,
gnu_java_awt_peer_gtk_GtkWindowPeer.c (postConfigureEvent):
Prevent callback calling back into peers.
(setBounds): Likewise.
(nativeSetBoundsUnlocked): New method.
(setBoundsUnlocked): Likewise.
(nativeSetVisibleUnlocked): Likewise.
(setVisibleUnlocked): Likewise.
(window_delete_cb): Don't release GDK lock.
(window_destroy_cb): Likewise.
(window_show_cb): Likewise.
(window_active_state_change_cb): Likewise.
(window_focus_state_change_cb): Likewise.
(window_focus_in_cb): Likewise.
(window_focus_out_cb): Likewise.
(window_window_state_cb): Likewise.
(window_property_changed_cb): Likewise.
(realize_cb): Likewise.
* gnu/java/awt/peer/gtk/GtkToolkit.java (mainThread): New
variable.
* gnu/java/awt/peer/gtk/GtkFileDialogPeer.java,
gnu_java_awt_peer_gtk_GtkFileDialogPeer.c (setVisible): Prevent
callback calling back into peers.
(filename_filter_cb): Don't release GDK lock.
(handle_response_cb): Likewise.
(cp_gtk_filedialog_init_jni): New function.
* gnu/java/awt/peer/gtk/GtkCheckboxPeer.java (setState): Prevent
callback from calling back into peers.
(item_toggled_cb): Don't release GDK lock.
* gnu/java/awt/peer/gtk/GdkPixbufDecoder.java,
gnu_java_awt_peer_gtk_GdkPixbufDecoder.c (area_prepared_cb): Don't
release GDK lock.
(area_updated_cb): Likewise.
* gnu/java/awt/peer/gtk/GdkGraphics2D.java,
gnu_java_awt_peer_gtk_GdkGraphics2D.c (initStateUnlocked): New
method.
(cairoSurfaceSetFilterUnlocked): Likewise.
(initComponentGraphics2DUnlocked): Likewise.
(setTexturePixelsUnlocked): Likewise.
(setGradientUnlocked): Likewise.
(cairoSetMatrixUnlocked): Likewise.
(cairoSetRGBAColorUnlocked): Likewise.
(cairoSetLineWidthUnlocked): Likewise.
(cairoSetLineCapUnlocked): Likewise.
(cairoSetLineJoinUnlocked): Likewise.
(cairoSetDashUnlocked): Likewise.
(cairoSetMiterLimitUnlocked): Likewise.
(setPaintUnlocked): Likewise.
(setTransformUnlocked): Likewise.
(setStrokeUnlocked): Likewise.
(setColorUnlocked): Likewise.
(setBackgroundUnlocked): Likewise.
(setRenderingHintsUnlocked): Likewise.
(setFontUnlocked): Likewise.
(realize_cb): Don't release GDK lock. Call
initComponentGraphics2DUnlocked.
* gnu/java/awt/peer/gtk/GdkGraphics.java,
gnu_java_awt_peer_gtk_GdkGraphics.c (initStateUnlocked): New
method.
(initComponentGraphicsUnlocked): New method.
(realize_cb): Don't release GDK lock. Call
initComponentGraphicsUnlocked.
* include/gnu_java_awt_peer_gtk_GdkGraphics.h: Regenerate.
* include/gnu_java_awt_peer_gtk_GdkGraphics2D.h: Likewise.
* include/gnu_java_awt_peer_gtk_GtkFramePeer.h: Likewise.
* include/gnu_java_awt_peer_gtk_GtkWindowPeer.h: Likewise.
Diffstat (limited to 'gnu/java')
| -rw-r--r-- | gnu/java/awt/peer/gtk/GdkGraphics.java | 10 | ||||
| -rw-r--r-- | gnu/java/awt/peer/gtk/GdkGraphics2D.java | 161 | ||||
| -rw-r--r-- | gnu/java/awt/peer/gtk/GdkPixbufDecoder.java | 4 | ||||
| -rw-r--r-- | gnu/java/awt/peer/gtk/GtkCheckboxPeer.java | 12 | ||||
| -rw-r--r-- | gnu/java/awt/peer/gtk/GtkFileDialogPeer.java | 27 | ||||
| -rw-r--r-- | gnu/java/awt/peer/gtk/GtkFramePeer.java | 20 | ||||
| -rw-r--r-- | gnu/java/awt/peer/gtk/GtkToolkit.java | 14 | ||||
| -rw-r--r-- | gnu/java/awt/peer/gtk/GtkWindowPeer.java | 35 |
8 files changed, 270 insertions, 13 deletions
diff --git a/gnu/java/awt/peer/gtk/GdkGraphics.java b/gnu/java/awt/peer/gtk/GdkGraphics.java index 65c01b86e..9a5195629 100644 --- a/gnu/java/awt/peer/gtk/GdkGraphics.java +++ b/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -78,6 +78,7 @@ public class GdkGraphics extends Graphics static final int GDK_COPY = 0, GDK_XOR = 2; native void initState (GtkComponentPeer component); + native void initStateUnlocked (GtkComponentPeer component); native void initState (int width, int height); native void initFromImage (GtkImage image); native void copyState (GdkGraphics g); @@ -131,6 +132,15 @@ public class GdkGraphics extends Graphics clip = new Rectangle (0, 0, d.width, d.height); } + // called back by native side: realize_cb + void initComponentGraphicsUnlocked () + { + initStateUnlocked (component); + color = component.awtComponent.getForeground (); + Dimension d = component.awtComponent.getSize (); + clip = new Rectangle (0, 0, d.width, d.height); + } + native void connectSignals (GtkComponentPeer component); public native void clearRect(int x, int y, int width, int height); diff --git a/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/gnu/java/awt/peer/gtk/GdkGraphics2D.java index b8203179d..3563ca9dc 100644 --- a/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -132,12 +132,14 @@ public class GdkGraphics2D extends Graphics2D Composite comp; private Stack stateStack; + private native void initStateUnlocked(GtkComponentPeer component); private native void initState(GtkComponentPeer component); private native void initState(int width, int height); private native void initState(int[] pixes, int width, int height); private native void copyState(GdkGraphics2D g); public native void dispose(); private native void cairoSurfaceSetFilter(int filter); + private native void cairoSurfaceSetFilterUnlocked(int filter); native void connectSignals(GtkComponentPeer component); public void finalize() @@ -236,6 +238,21 @@ public class GdkGraphics2D extends Graphics2D stateStack = new Stack(); } + void initComponentGraphics2DUnlocked() + { + initStateUnlocked(component); + + setColorUnlocked(component.awtComponent.getForeground()); + setBackgroundUnlocked(component.awtComponent.getBackground()); + setPaintUnlocked(getColorUnlocked()); + setTransformUnlocked(new AffineTransform()); + setStrokeUnlocked(new BasicStroke()); + setRenderingHintsUnlocked(getDefaultHints()); + setFontUnlocked(new Font("SansSerif", Font.PLAIN, 12)); + + stateStack = new Stack(); + } + GdkGraphics2D(BufferedImage bimage) { this.bimage = bimage; @@ -280,25 +297,37 @@ public class GdkGraphics2D extends Graphics2D // drawing utility methods private native void drawPixels(int[] pixels, int w, int h, int stride, double[] i2u); + private native void setTexturePixelsUnlocked(int[] pixels, int w, int h, int stride); private native void setTexturePixels(int[] pixels, int w, int h, int stride); private native void setGradient(double x1, double y1, double x2, double y2, int r1, int g1, int b1, int a1, int r2, int g2, int b2, int a2, boolean cyclic); + private native void setGradientUnlocked(double x1, double y1, double x2, double y2, + int r1, int g1, int b1, int a1, int r2, + int g2, int b2, int a2, boolean cyclic); // simple passthroughs to cairo private native void cairoSave(); private native void cairoRestore(); private native void cairoSetMatrix(double[] m); + private native void cairoSetMatrixUnlocked(double[] m); private native void cairoSetOperator(int cairoOperator); private native void cairoSetRGBAColor(double red, double green, double blue, double alpha); + private native void cairoSetRGBAColorUnlocked(double red, double green, + double blue, double alpha); private native void cairoSetFillRule(int cairoFillRule); private native void cairoSetLineWidth(double width); + private native void cairoSetLineWidthUnlocked(double width); private native void cairoSetLineCap(int cairoLineCap); + private native void cairoSetLineCapUnlocked(int cairoLineCap); private native void cairoSetLineJoin(int cairoLineJoin); + private native void cairoSetLineJoinUnlocked(int cairoLineJoin); private native void cairoSetDash(double[] dashes, int ndash, double offset); + private native void cairoSetDashUnlocked(double[] dashes, int ndash, double offset); private native void cairoSetMiterLimit(double limit); + private native void cairoSetMiterLimitUnlocked(double limit); private native void cairoNewPath(); private native void cairoMoveTo(double x, double y); private native void cairoLineTo(double x, double y); @@ -689,6 +718,49 @@ public class GdkGraphics2D extends Graphics2D throw new java.lang.UnsupportedOperationException(); } + public void setPaintUnlocked(Paint p) + { + if (paint == null) + return; + + paint = p; + if (paint instanceof Color) + { + setColorUnlocked((Color) paint); + } + else if (paint instanceof TexturePaint) + { + TexturePaint tp = (TexturePaint) paint; + BufferedImage img = tp.getImage(); + + // map the image to the anchor rectangle + int width = (int) tp.getAnchorRect().getWidth(); + int height = (int) tp.getAnchorRect().getHeight(); + + double scaleX = width / (double) img.getWidth(); + double scaleY = width / (double) img.getHeight(); + + AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0); + AffineTransformOp op = new AffineTransformOp(at, getRenderingHints()); + BufferedImage texture = op.filter(img, null); + int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width); + setTexturePixelsUnlocked(pixels, width, height, width); + } + else if (paint instanceof GradientPaint) + { + GradientPaint gp = (GradientPaint) paint; + Point2D p1 = gp.getPoint1(); + Point2D p2 = gp.getPoint2(); + Color c1 = gp.getColor1(); + Color c2 = gp.getColor2(); + setGradientUnlocked(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(), + c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(), + c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic()); + } + else + throw new java.lang.UnsupportedOperationException(); + } + public void setTransform(AffineTransform tx) { transform = tx; @@ -700,6 +772,17 @@ public class GdkGraphics2D extends Graphics2D } } + public void setTransformUnlocked(AffineTransform tx) + { + transform = tx; + if (transform != null) + { + double[] m = new double[6]; + transform.getMatrix(m); + cairoSetMatrixUnlocked(m); + } + } + public void transform(AffineTransform tx) { if (transform == null) @@ -787,6 +870,28 @@ public class GdkGraphics2D extends Graphics2D } } + public void setStrokeUnlocked(Stroke st) + { + stroke = st; + if (stroke instanceof BasicStroke) + { + BasicStroke bs = (BasicStroke) stroke; + cairoSetLineCapUnlocked(bs.getEndCap()); + cairoSetLineWidthUnlocked(bs.getLineWidth()); + cairoSetLineJoinUnlocked(bs.getLineJoin()); + cairoSetMiterLimitUnlocked(bs.getMiterLimit()); + float[] dashes = bs.getDashArray(); + if (dashes != null) + { + double[] double_dashes = new double[dashes.length]; + for (int i = 0; i < dashes.length; i++) + double_dashes[i] = dashes[i]; + cairoSetDashUnlocked(double_dashes, double_dashes.length, + (double) bs.getDashPhase()); + } + } + } + //////////////////////////////////////////////// ////// Implementation of Graphics Methods ////// //////////////////////////////////////////////// @@ -812,11 +917,27 @@ public class GdkGraphics2D extends Graphics2D fg.getBlue() / 255.0, fg.getAlpha() / 255.0); } + public void setColorUnlocked(Color c) + { + if (c == null) + c = Color.BLACK; + + fg = c; + paint = c; + cairoSetRGBAColorUnlocked(fg.getRed() / 255.0, fg.getGreen() / 255.0, + fg.getBlue() / 255.0, fg.getAlpha() / 255.0); + } + public Color getColor() { return fg; } + public Color getColorUnlocked() + { + return getColor(); + } + public void clipRect(int x, int y, int width, int height) { clip(new Rectangle(x, y, width, height)); @@ -929,6 +1050,11 @@ public class GdkGraphics2D extends Graphics2D bg = c; } + public void setBackgroundUnlocked(Color c) + { + setBackground(c); + } + public Color getBackground() { return bg; @@ -1180,6 +1306,36 @@ public class GdkGraphics2D extends Graphics2D || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); } + public void setRenderingHintsUnlocked(Map hints) + { + this.hints = new RenderingHints(getDefaultHints()); + this.hints.add(new RenderingHints(hints)); + + if (hints.containsKey(RenderingHints.KEY_INTERPOLATION)) + { + if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) + cairoSurfaceSetFilterUnlocked(0); + + else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) + cairoSurfaceSetFilterUnlocked(1); + } + + if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION)) + { + if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) + cairoSurfaceSetFilterUnlocked(2); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) + cairoSurfaceSetFilterUnlocked(3); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) + cairoSurfaceSetFilterUnlocked(4); + } + + shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); + } + public void addRenderingHints(Map hints) { this.hints.add(new RenderingHints(hints)); @@ -1443,6 +1599,11 @@ public class GdkGraphics2D extends Graphics2D .getFont(f.getName(), f.getAttributes()); } + public void setFontUnlocked(Font f) + { + setFont (f); + } + public String toString() { return (getClass().getName() diff --git a/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java index 57d5a36da..90bef8495 100644 --- a/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java +++ b/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -122,7 +122,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder super (imagedata, imageoffset, imagelength); } - // called back by native side + // called back by native side: area_prepared_cb void areaPrepared (int width, int height) { @@ -138,7 +138,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder } } - // called back by native side + // called back by native side: area_updated_cb void areaUpdated (int x, int y, int width, int height, int pixels[], int scansize) { diff --git a/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java b/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java index 851757245..3e05cf8ab 100644 --- a/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java +++ b/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java @@ -49,6 +49,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer public GtkCheckboxGroupPeer old_group; // The current state of the GTK checkbox. private boolean currentState; + private boolean changing = false; public native void create (GtkCheckboxGroupPeer group); public native void nativeSetCheckboxGroup (GtkCheckboxGroupPeer group); @@ -76,6 +77,15 @@ public class GtkCheckboxPeer extends GtkComponentPeer public void setState (boolean state) { + // prevent item_toggled_cb -> postItemEvent -> + // awtComponent.setState -> this.setState -> + // gtkToggleButtonSetActive self-deadlock on the GDK lock. + if (changing && Thread.currentThread() == GtkToolkit.mainThread) + { + changing = false; + return; + } + if (currentState != state) gtkToggleButtonSetActive (state); } @@ -100,6 +110,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer // Override the superclass postItemEvent so that the peer doesn't // need information that we have. + // called back by native side: item_toggled_cb public void postItemEvent (Object item, int stateChange) { Checkbox currentCheckBox = ((Checkbox)awtComponent); @@ -113,6 +124,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer { super.postItemEvent (awtComponent, stateChange); currentState = !currentCheckBox.getState(); + changing = true; currentCheckBox.setState(currentState); } } diff --git a/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java b/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java index a2bd609d4..7a6b94d90 100644 --- a/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java +++ b/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java @@ -62,6 +62,8 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer public native void nativeSetDirectory(String directory); native void nativeSetFilenameFilter (FilenameFilter filter); + private boolean hiding = false; + public void create() { create((GtkContainerPeer) awtComponent.getParent().getPeer()); @@ -156,6 +158,7 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer GtkFileFilterInfo object and send it to this method, which will in turn call the filter's accept() method and give back the return value. */ + // called back by native side: filename_filter_cb boolean filenameFilterCallback (String fullname) { String filename = fullname.substring(fullname.lastIndexOf(FS) + 1); String dirname = fullname.substring(0, fullname.lastIndexOf(FS)); @@ -169,19 +172,37 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer return null; } + public void setVisible (boolean b) + { + // prevent handle_response_cb -> postItemEvent -> awtComponent.setState -> this.setState + // -> gtkToggleButtonSetActive self-deadlock on the GDK lock. + if (hiding && Thread.currentThread() == GtkToolkit.mainThread) + { + setVisibleUnlocked (b); + hiding = false; + } + else + super.setVisible (b); + } + + // called back by native side: handle_response_cb void gtkHideFileDialog () { + // hide calls back the peer's setVisible method, so locking is a + // problem. + hiding = true; ((Dialog) awtComponent).hide(); } + // called back by native side: handle_response_cb void gtkDisposeFileDialog () { ((Dialog) awtComponent).dispose(); } - /* Callback to set the file and directory values when the user is finished - * with the dialog. - */ + // Callback to set the file and directory values when the user is finished + // with the dialog. + // called back by native side: handle_response_cb void gtkSetFilename (String fileName) { FileDialog fd = (FileDialog) awtWidget; diff --git a/gnu/java/awt/peer/gtk/GtkFramePeer.java b/gnu/java/awt/peer/gtk/GtkFramePeer.java index 8def405d2..c7f197405 100644 --- a/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -56,11 +56,14 @@ public class GtkFramePeer extends GtkWindowPeer private int menuBarHeight; private MenuBarPeer menuBar; native int getMenuBarHeight (MenuBarPeer bar); + native void setMenuBarWidthUnlocked (MenuBarPeer bar, int width); native void setMenuBarWidth (MenuBarPeer bar, int width); native void setMenuBarPeer (MenuBarPeer bar); native void removeMenuBarPeer (); native void gtkFixedSetVisible (boolean visible); + private boolean resizing = false; + int getMenuBarHeight () { return menuBar == null ? 0 : getMenuBarHeight (menuBar); @@ -118,6 +121,18 @@ public class GtkFramePeer extends GtkWindowPeer public void setBounds (int x, int y, int width, int height) { + // prevent window_configure_cb -> awtComponent.setSize -> + // peer.setBounds -> nativeSetBounds self-deadlock on GDK lock. + if (resizing && Thread.currentThread() == GtkToolkit.mainThread) + { + int menuBarWidth = width - insets.left - insets.right; + if (menuBar != null && menuBarWidth > 0) + setMenuBarWidthUnlocked (menuBar, menuBarWidth); + + resizing = false; + return; + } + int menuBarWidth = width - insets.left - insets.right; if (menuBar != null && menuBarWidth > 0) setMenuBarWidth (menuBar, menuBarWidth); @@ -200,7 +215,10 @@ public class GtkFramePeer extends GtkWindowPeer if (frame_width != awtComponent.getWidth() || frame_height != awtComponent.getHeight()) - awtComponent.setSize(frame_width, frame_height); + { + resizing = true; + awtComponent.setSize(frame_width, frame_height); + } int frame_x = x - insets.left; // Likewise, since insets.top includes the MenuBar height, we need diff --git a/gnu/java/awt/peer/gtk/GtkToolkit.java b/gnu/java/awt/peer/gtk/GtkToolkit.java index ef97685a3..70957b9df 100644 --- a/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -90,6 +90,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit static EventQueue q; static boolean useGraphics2dSet; static boolean useGraphics2d; + static Thread mainThread; public static boolean useGraphics2D() { @@ -124,13 +125,14 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit // Register ImageIO SPIs GdkPixbufDecoder.registerSpis( IIORegistry.getDefaultInstance() ); - new Thread ("GTK main thread") - { - public void run () + mainThread = new Thread ("GTK main thread") { - gtkMain (); - } - }.start (); + public void run () + { + gtkMain (); + } + }; + mainThread.start (); } public GtkToolkit () diff --git a/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/gnu/java/awt/peer/gtk/GtkWindowPeer.java index 32e4cee44..518c52662 100644 --- a/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -60,6 +60,8 @@ public class GtkWindowPeer extends GtkContainerPeer private boolean hasBeenShown = false; private int oldState = Frame.NORMAL; + private boolean resizing = false; + native void gtkWindowSetTitle (String title); native void gtkWindowSetResizable (boolean resizable); native void gtkWindowSetModal (boolean modal); @@ -116,14 +118,29 @@ public class GtkWindowPeer extends GtkContainerPeer public native void toFront(); native void nativeSetBounds (int x, int y, int width, int height); + native void nativeSetBoundsUnlocked (int x, int y, int width, int height); public void setBounds (int x, int y, int width, int height) { + // prevent window_configure_cb -> awtComponent.setSize -> + // peer.setBounds -> nativeSetBounds self-deadlock on GDK lock. + if (resizing && Thread.currentThread() == GtkToolkit.mainThread) + { + resizing = false; + return; + } nativeSetBounds (x, y, width - insets.left - insets.right, height - insets.top - insets.bottom); } + public void setBoundsUnlocked (int x, int y, int width, int height) + { + nativeSetBoundsUnlocked (x, y, + width - insets.left - insets.right, + height - insets.top - insets.bottom); + } + public void setTitle (String title) { gtkWindowSetTitle (title); @@ -157,7 +174,10 @@ public class GtkWindowPeer extends GtkContainerPeer if (frame_width != awtComponent.getWidth() || frame_height != awtComponent.getHeight()) - awtComponent.setSize(frame_width, frame_height); + { + resizing = true; + awtComponent.setSize(frame_width, frame_height); + } int frame_x = x - insets.left; int frame_y = y - insets.top; @@ -182,6 +202,19 @@ public class GtkWindowPeer extends GtkContainerPeer nativeSetVisible (b); } + native void nativeSetVisibleUnlocked (boolean b); + public void setVisibleUnlocked (boolean b) + { + // Prevent the window manager from automatically placing this + // window when it is shown. + if (b) + setBoundsUnlocked (awtComponent.getX(), + awtComponent.getY(), + awtComponent.getWidth(), + awtComponent.getHeight()); + nativeSetVisibleUnlocked (b); + } + void postWindowEvent (int id, Window opposite, int newState) { if (id == WindowEvent.WINDOW_OPENED) |
