Pages: [1]   Go Down
Author Topic: BUG: Serial Monitor keyboard shortcut inserts CR  (Read 898 times)
0 Members and 1 Guest are viewing this topic.
Lincoln, NE
Offline Offline
Full Member
***
Karma: 0
Posts: 106
Having lots of fun with Arduino. Thanks everyone!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I noticed that sometimes the Arduino IDE would randomly destroy my code in the editor.  It could be as harmless as changing number of spaces between functions, or as bad as renaming my variables or missing code chunks.

It turned out that everytime I press the Serial Monitor keyboard shortcut: CTRL+SHIFT+M

Not only the Serial Monitor would open, but Arduino IDE also types a Carriage Return character WHEREVER my selection happens to be!  If I have code selected, it would be removed and replaced with a return.

Not cool... :-(

I'm running Arduino 0018 on 32-bit Windows Vista Ultimate.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Same here on 64bit Kubuntu Linux.

Its only happened with the shortcut, if I use the Menu it works correct.
(Arduino 0018)

Logged

Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 83
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

On Windows XP, I have noticed the same and was looking for some information before posting this as a bug.

There isn't  much information here yet. So lets try to improve this.

What I think is happening, is that pressing Ctrl-Shift-M triggers an event that opens the Serial Monitor, though this event isn't consumed. So then the event continues it's travel through the application and ends up in the textfield where it represents a CR.
A CR can often be entered using Ctrl-M (it's even sometimes represented by ^M, which is a notation for Ctrl-M). You can confirm this by pressing Ctrl-M or Ctrl-Shift-M in Notepad (Windows).

Looking into a solution for a minute, I have come across a consume() method in the ActionEvent. It is however protected, and cannot be called from the Arduino source. I am not familiar with a solution for this.

Any other Java developers who can help solving this really annoying bug?

I might look into it some more later this week. I'll post any updates.

Edit: some findings up till now

I have created a independent test app to try to reproduce the bug in a less-code app.
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ConsumeTest extends JFrame {
      public ConsumeTest() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            JMenuBar menuBar = new JMenuBar();
            JMenu menu = new JMenu("Menu");
            menuBar.add(menu);

            JMenuItem ctrlMTestItem = new JMenuItem("Ctrl M Test");
            int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
            modifiers |= ActionEvent.SHIFT_MASK;
            ctrlMTestItem.setAccelerator(KeyStroke.getKeyStroke('M', modifiers));
            ctrlMTestItem.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent e) {
                        System.out.println("Action taken");
                  }
            });
            menu.add(ctrlMTestItem);

            setJMenuBar(menuBar);

            JTextArea textArea = new JTextArea();
            getContentPane().add(textArea);

            setPreferredSize(new Dimension(400, 300));
            setMinimumSize(new Dimension(400, 300));
      }

      public static void main(String[] arg) {
            new ConsumeTest().setVisible(true);
      }
}

When trying to create the bug, I noticed that my app doesn't even insert a newline when pressing Ctrl(-Shift)-M. So my guess is that Arduino interprets the keystroke somehow, and that's where the possible error is. I haven't been able to track down where the Ctrl-M keystroke is handled and the CR is inserted. Any suggestions where this happens? (I have tried to find it in processing.app.syntax.DefaultInputHandler)
« Last Edit: April 05, 2010, 04:30:59 pm by qistoph » Logged

Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 83
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have found what goes wrong.

In processing.app.syntax.JEditTextarea, in the method processKeyEvent, the KeyEvent is passed through all the handlers.
First by 'super', then editorListener and finally inputHandler.

The consume status possibly set by super.processKeyEvent is, however, ignored.

Unfortunately, when I tried changing the code so it looks at the consumed status after the call to 'super', some other functionality (like cursor keys) no longer works.

Here's what I've tried:
Code:
 public void processKeyEvent(KeyEvent evt) {
        System.out.println("evt.isConsumed (1): " + evt.isConsumed());
    // this had to be added in Processing 007X, because the menu key
    // events weren't making it up to the frame.
    super.processKeyEvent(evt);

        System.out.println("evt.isConsumed (2): " + evt.isConsumed());

[glow]    // Don't handle events that have been handled already
            if(evt.isConsumed()) return;[/glow]

    //System.out.println("jedittextarea: " + evt);
    //System.out.println();
    if (inputHandler == null) return;

    switch(evt.getID()) {
    case KeyEvent.KEY_TYPED:
      if ((editorListener == null) || !editorListener.keyTyped(evt)) {
        inputHandler.keyTyped(evt);
      }
      break;
    case KeyEvent.KEY_PRESSED:
      if ((editorListener == null) || !editorListener.keyPressed(evt)) {
        inputHandler.keyPressed(evt);
      }
      break;
    case KeyEvent.KEY_RELEASED:
      inputHandler.keyReleased(evt);
      break;
    }
  }

This bug will probably end up being ignored, since the error actually is in the Processing code. Though there's no real reason to fix it in Processing I guess, since they don't have this conflict.
« Last Edit: April 06, 2010, 08:02:30 am by qistoph » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you return only if the event was consumed AND is Ctrl-Shift-M?
Logged

Netherlands
Offline Offline
Jr. Member
**
Karma: 0
Posts: 83
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

PaulS, I think that would be possible.
But I was looking for a more solid solution.
One that'll work for possible future shortcuts too.

This code, not thoroughly tested, should do that.
Code:
   if(evt.isConsumed() && evt.getKeyCode() == KeyEvent.VK_M && evt.getModifiers() == (InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK))
          return;
Logged

Pages: [1]   Go Up
Jump to: