Opened 3 years ago

Last modified 18 months ago

#17611 new defect

Accelerators not using modifiers (or using only Shift) don't work in wxGTK when a wxPanel is focused

Reported by: jerome_mao Owned by:
Priority: normal Milestone:
Component: wxGTK Version: 3.0.2
Keywords: accelerator Cc: jerome_mao@…
Blocked By: Blocking:
Patch: no

Description

OS: Linux CentOS 6.3 WX 3.0.2
Quesiton: HotKey Invalid

I updated wx from wx2.8 to wx3.0, there has a problem about hotkey,

some hotkey in subwindow don't work on linux platform with wx3.0.2(windows is ok), i have no diea about it, it's need to solve as soon as possiable, so please help to check it ,thx a lot.

example: all the plain letter keys that I tested fail in subwindow

#include <wx/wx.h>

#define ID_OPENSUBWIN 1000
#define ID_EXITWIN 1001
#define ID_TIPWARNING 1002
#define ID_K 10001
#define ID_SHK 10002
#define ID_CTLK 10003
#define ID_F 10004
#define ID_SHF 10005
#define ID_CTLF 10006
#define ID_F9 10007
#define ID_SHF9 10008
#define ID_CTLF9 10009
#define ID_EXITSUBWIN 1003

class CSubWindow : public wxFrame
{
public:
   CSubWindow(wxWindow *parent);

   void OnMenu(wxCommandEvent& event);
   void OnClose(wxCloseEvent& event);

   DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(CSubWindow, wxFrame)
    EVT_CLOSE(CSubWindow::OnClose)
    EVT_MENU(ID_TIPWARNING, CSubWindow::OnMenu)
    EVT_MENU_RANGE(ID_TIPWARNING, ID_CTLF9, CSubWindow::OnMenu)
END_EVENT_TABLE()

CSubWindow::CSubWindow(wxWindow *parent) : wxFrame(parent, -1, wxT("SubWindow"), wxDefaultPosition, wxSize(600, 600))
{
   wxMenuBar *menubar = new wxMenuBar();
   wxMenu* fileMenu = new wxMenu;
   fileMenu->Append(ID_TIPWARNING, wxT("&Warning dlg: O\tO"));
   fileMenu->Append(ID_K, wxT("K\tK"));
   fileMenu->Append(ID_SHK, wxT("SH-K\tShift-K"));
   fileMenu->Append(ID_CTLK, wxT("Ctrl-K\tCtrl-K"));
   fileMenu->Append(ID_F, wxT("F\tF"));
   fileMenu->Append(ID_SHF, wxT("SH F\tShift-F"));
   fileMenu->Append(ID_CTLF, wxT("CTL F\tCtrl-F"));
   fileMenu->Append(ID_F9, wxT("F9\tF9"));
   fileMenu->Append(ID_SHF9, wxT("SH F9\tShift-F9"));
   fileMenu->Append(ID_CTLF9, wxT("CTL F9\tCtrl-F9"));
   fileMenu->AppendSeparator();
   fileMenu->Append(ID_EXITSUBWIN, wxT("E&xit\tCtrl+Q"));
   menubar->Append(fileMenu, wxT("Window"));
   SetMenuBar(menubar);
   wxPanel *panel = new wxPanel(this);

   wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
   mainSizer->Add(panel, 1, wxEXPAND);

   SetSizer(mainSizer);
   SetAutoLayout(true);
}

void CSubWindow::OnMenu(wxCommandEvent& event)
{
   if (event.GetId() == ID_TIPWARNING)
   {
      wxMessageDialog dlg(this, wxT("Tip Window"));
      dlg.ShowModal();
   }
   else if (event.GetId() == ID_EXITSUBWIN)
   {
      this->Destroy();
   }
   else 
   {
      wxMessageDialog dlg(this, wxString::Format( wxT("ID %i pressed"), event.GetId()) );
      dlg.ShowModal();
   }

   event.Skip();
}

void CSubWindow::OnClose(wxCloseEvent& event)
{
   Destroy();
}

class CTestMainWindow :public wxFrame
{
public:
   CTestMainWindow(wxWindow* parent);
   void OnClose(wxCloseEvent& event);
   void OnMenu(wxCommandEvent& event);

   DECLARE_EVENT_TABLE()
};

BEGIN_EVENT_TABLE(CTestMainWindow, wxFrame)
    EVT_CLOSE(CTestMainWindow::OnClose)
    EVT_MENU(ID_OPENSUBWIN,CTestMainWindow::OnMenu)
    EVT_MENU(ID_EXITWIN, CTestMainWindow::OnMenu)
END_EVENT_TABLE()

CTestMainWindow::CTestMainWindow(wxWindow* parent) : wxFrame(parent, -1, wxT("MainWindow"), wxDefaultPosition, wxSize(720,680))
{
   wxMenuBar *menubar = new wxMenuBar();
   wxMenu* fileMenu = new wxMenu;
   fileMenu->Append(ID_OPENSUBWIN, wxT("&Open..\tO"));
   fileMenu->AppendSeparator();
   fileMenu->Append(ID_EXITWIN, wxT("E&xit\tCtrl+X"));
   menubar->Append(fileMenu, wxT("Window"));

   SetMenuBar(menubar);
}
void CTestMainWindow::OnClose(wxCloseEvent& event)
{
   Destroy();
}
void CTestMainWindow::OnMenu(wxCommandEvent& event)
{
   int evtid = event.GetId();
   if (evtid == ID_OPENSUBWIN)
   {
      CSubWindow* subwindow = new CSubWindow(this);
      subwindow->Show();
   }
   else if (evtid == ID_EXITWIN)
   {
      Destroy();
   }
   event.Skip();
}
class CTestApp : public wxApp
{
public:
   CTestApp();
   bool   OnInit(void);
   int   OnExit(void);

protected:
   
   CTestMainWindow *frame;
};
IMPLEMENT_APP(CTestApp)
CTestApp::CTestApp()
{
}

bool CTestApp::OnInit()
{
   frame = new CTestMainWindow(NULL);
   frame->CentreOnScreen(wxBOTH);
   frame->Show(TRUE);

   SetTopWindow(frame);

   return true;
}
int CTestApp::OnExit(void)
{
   return wxApp::OnExit();
}

Change History (14)

comment:1 follow-up: Changed 3 years ago by vadz

  • Component changed from wxMSW to wxGTK
  • Milestone 3.0.3 deleted
  • Priority changed from critical to normal
  • Status changed from new to infoneeded_new

What do you mean by "hotkey"? Do you mean menu accelerators? If so, which one? "O" in the example above?

comment:2 in reply to: ↑ 1 Changed 3 years ago by jerome_mao

  • Status changed from infoneeded_new to new

Replying to vadz:

What do you mean by "hotkey"? Do you mean menu accelerators? If so, which one? "O" in the example above?

Hi yes, menu accelerators in subwindow. 'O' 'K' 'F' 'Shift+F' 'Shift+K' are all invalid on linux platform,others are worked

comment:3 follow-up: Changed 3 years ago by vadz

Please try reproducing the problem in the keyboard sample which already uses accelerators. Does it work for you there? If it does, try to find what do you do differently from the sample. If it doesn't, I'm really not sure what could be the reason as it's definitely supposed to work. What is your version of GTK+?

comment:4 in reply to: ↑ 3 Changed 3 years ago by jerome_mao

Replying to vadz:

Please try reproducing the problem in the keyboard sample which already uses accelerators. Does it work for you there? If it does, try to find what do you do differently from the sample. If it doesn't, I'm really not sure what could be the reason as it's definitely supposed to work. What is your version of GTK+?

GTK Version: 2.18.9

I reported this question to the wxwidgets.org before, and DavidHart replied
that

I tested on debian jessie, kde, gtk+2, and fedora 24 gnome, gtk+3. I confirm that there is a difference between wx2.8 and wx3:
In 2.8 all keys are usable as menu shortcuts.

Without the panel, all keys that I tested are usable as menu shortcuts.

In both wx3.0.2 and git head, all the plain letter keys that I tested fail, and so do SHIFT-<letter>. However Ctrl-<letter> works, and so do the function keys e.g. F9, SHIFT-F9, Ctrl-F9.
I suppose this is a bug, especially as it works in wxMSW and it's a regression from wx2.8. However most people won't have an empty panel inside a child frame, and most people won't wish to use 'O' etc as menu shortcuts.
If you feel it should be reported though, bug-reports go to wxtrac." ==

comment:5 follow-up: Changed 3 years ago by vadz

  • Keywords accelerator added; hotkey invalid removed
  • Summary changed from hotkey invlid in linux platform (wx3.0) to Accelerators not using modifiers (or using only Shift) don't work in wxGTK when a wxPanel is focused

Hmm, so it looks like normal keys (without "Ctrl") get eaten by the panel. Does it also happen if you replace it with plain wxWindow and/or create a child of the panel (but don't give it focus as otherwise it would definitely consume the keys)?

comment:6 Changed 3 years ago by jerome_mao

Yes, if the subwindow has no panel, the hotkeys all worked.
And if the focus not on the panel, give it to the toolbar for example, the hotkey are ok too.

comment:7 in reply to: ↑ 5 ; follow-ups: Changed 3 years ago by jerome_mao

Replying to vadz:

Hmm, so it looks like normal keys (without "Ctrl") get eaten by the panel. Does it also happen if you replace it with plain wxWindow and/or create a child of the panel (but don't give it focus as otherwise it would definitely consume the keys)?

Yes, if the subwindow has no panel, the hotkeys all worked.

And if the focus not on the panel, give it to the toolbar for example, the hotkey are ok too. do you know how to solve it? it seems related about event.

comment:8 in reply to: ↑ 7 Changed 3 years ago by jerome_mao

Replying to jerome_mao:

Replying to vadz:

Hmm, so it looks like normal keys (without "Ctrl") get eaten by the panel. Does it also happen if you replace it with plain wxWindow and/or create a child of the panel (but don't give it focus as otherwise it would definitely consume the keys)?

Yes, if the subwindow has no panel, the hotkeys all worked.

And if the focus not on the panel, give it to the toolbar for example, the hotkey are ok too. do you know how to solve it? it seems related about event.

Hi:

How's it going? Since we need to solve the question as soon as possiable,

Hope you can help us solve the question. Thanks a lot!

comment:9 Changed 3 years ago by vadz

Sorry, I don't have any plans to work on this in the immediate future. I don't know how to fix this, and the bug doesn't have very high priority as it should be possible to work around it by just using a wxWindow instead of wxPanel, IIUC.

If fixing it is critical for you, please try debugging it, any patches fixing the problem would, of course, be welcome.

comment:10 in reply to: ↑ 7 Changed 3 years ago by dghart

Replying to jerome_mao:

Replying to vadz:

Hmm, so it looks like normal keys (without "Ctrl") get eaten by the panel. Does it also happen if you replace it with plain wxWindow and/or create a child of the panel (but don't give it focus as otherwise it would definitely consume the keys)?

Yes, if the subwindow has no panel, the hotkeys all worked.

And if the focus not on the panel, give it to the toolbar for example, the hotkey are ok too. do you know how to solve it? it seems related about event.

To clarify this:
1) Replacing the panel with a wxWindow makes no difference.
2) Adding a wxWindow to the panel does: all keys work again.

So your workaround should be to change CSubWindow::CSubWindow to:

   ...
   wxPanel *panel = new wxPanel(this);
   wxWindow *win = new wxWindow(panel, -1);
   win->Hide();

comment:11 Changed 3 years ago by jerome_mao

Hi:

Our real code is not a panel in subwindow, it is a wxWindow instead of it.

So, wxWindow *win = new wxWindow(this), the hotkey all invalid in example.

comment:12 Changed 3 years ago by jerome_mao

sorry, not all invalid, 'Ctrl+K' 'Ctrl+F' 'Ctrl+F9' 'Ctrl+Q' 'Shift+F9' are worked.

comment:13 Changed 3 years ago by dghart

I (almost) confirm that: F9/ShiftF9/CtrlF9 all work, but not F/ShiftF K/ShiftK.

So it sounds as if your workaround is to change your wxWindow to derive from wxPanel instead, and then add a hidden child wxWindow as above. Doing this will probably not break your real code...

comment:14 Changed 18 months ago by pcor

A small patch to the minimal sample is all that is needed to reproduce the problem:

diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
index f765a70dac..81cc4b33b5 100644
--- a/samples/minimal/minimal.cpp
+++ b/samples/minimal/minimal.cpp
@@ -125,6 +125,7 @@ bool MyApp::OnInit()
 
     // create the main application window
     MyFrame *frame = new MyFrame("Minimal wxWidgets App");
+    new wxWindow(frame, wxID_ANY);
 
     // and show it (the frames, unlike simple controls, are not shown when
     // created initially)
@@ -154,6 +155,7 @@ MyFrame::MyFrame(const wxString& title)
     // the "About" item should be in the help menu
     wxMenu *helpMenu = new wxMenu;
     helpMenu->Append(Minimal_About, "&About\tF1", "Show about dialog");
+    helpMenu->Append(Minimal_About, "About\tA", "Show about dialog");
 
     fileMenu->Append(Minimal_Quit, "E&xit\tAlt-X", "Quit this program");
 

Running WXTRACE=keyevent ./minimal shows that the key is intercepted by the Input Method handler.

Note: See TracTickets for help on using tickets.