Skip to content

Fix Frame.setState() - #66

Open
duncanmcqueen wants to merge 1 commit into
ingelabs:masterfrom
duncanmcqueen:fix-frame-setstate
Open

duncanmcqueen wants to merge 1 commit into
ingelabs:masterfrom
duncanmcqueen:fix-frame-setstate

Conversation

@duncanmcqueen

Copy link
Copy Markdown
Contributor

Split from #58.

Problem and fix

Frame.setState() does the opposite of the request:

  • setState(ICONIFIED) on a normal frame calls setExtendedState(current & ~ICONIFIED). The frame stays normal.
  • setState(NORMAL) on an iconified frame calls setExtendedState(current | ICONIFIED). The frame stays iconified.

Also, the test for ICONIFIED is (current & ~ICONIFIED) == 0. Thus a maximized frame cannot become iconified.

Now NORMAL removes the ICONIFIED bit and ICONIFIED adds it. The other state bits do not change.

How to reproduce

The frame does not have to be visible. The test needs a display, because the GTK peer must start.

javac FrameSetState.java
java FrameSetState
FrameSetState.java
import java.awt.Frame;

/**
 * Frame.setState() must set the requested state. The frame does not need
 * to be visible. Needs a display (GTK peer).
 */
public class FrameSetState
{
  static boolean failed;

  static void check(String what, int got, int expected)
  {
    System.out.println((got == expected ? "PASS " : "FAIL ") + what
                       + ": getState() = " + got + ", expected " + expected);
    failed |= got != expected;
  }

  public static void main(String[] args)
  {
    Frame f = new Frame("FrameSetState");
    f.setState(Frame.ICONIFIED);
    check("setState(ICONIFIED)", f.getState(), Frame.ICONIFIED);
    f.setExtendedState(Frame.ICONIFIED);
    f.setState(Frame.NORMAL);
    check("setState(NORMAL) on an iconified frame", f.getState(), Frame.NORMAL);
    f.dispose();
    System.exit(failed ? 1 : 0);
  }
}

Results

Linux x86_64, ingelabs/classpath master (0406074), JamVM master, javac from JDK 8, autoconf 2.73, automake 1.19, the configure options of the CI Linux job, out-of-tree build. "Before" is master. "After" is master with this commit.

Before:
FAIL setState(ICONIFIED): getState() = 0, expected 1
FAIL setState(NORMAL) on an iconified frame: getState() = 1, expected 0

After:
PASS setState(ICONIFIED): getState() = 1, expected 1
PASS setState(NORMAL) on an iconified frame: getState() = 0, expected 0

OpenJDK 27 also gives the "After" result.

Platforms

Not specific to Haiku. The problem is in java.awt.Frame and occurs with all toolkits that support ICONIFIED. I reproduced it on Linux with the GTK peer.

AI assistance

An AI model (Claude Code, by Anthropic) wrote this change, the test and this text. The repository owner directed the work and checked the results. Please review it as you review other contributions.

🤖 Generated with Claude Code

@guillerodriguez

Copy link
Copy Markdown
Contributor

CI is failing because the Malva test suite now has a test for mmap :-)

Can you rebase on top of latest master (please rebase instead of adding a merge commit) and force push?

@guillerodriguez

Copy link
Copy Markdown
Contributor

Can you rebase on top of latest master (please rebase instead of adding a merge commit) and force push?

Nevermind, just did that myself :-)

@duncanmcqueen

Copy link
Copy Markdown
Contributor Author

Thank you!!!

setState(NORMAL) added ICONIFIED to an iconified frame and
setState(ICONIFIED) removed it, the opposite of the request. Remove
ICONIFIED for NORMAL and add it for ICONIFIED, and keep the other
state bits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: duncanmcqueen <dwmcqueen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants