Problem with single char EVT_MENU event on gtk. Topic is solved

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
oscar1919
Earned a small fee
Earned a small fee
Posts: 17
Joined: Tue Dec 11, 2018 10:40 am
Location: Belgium

Problem with single char EVT_MENU event on gtk.

Post by oscar1919 »

Hi all,

I am experiencing the following problem, which I tried to isolate in the code below, which is based on the minimal sample.
The wxWidgets version used is 3.1.1.
My window is a frame which has three menu accelerator keys, Alt-x, F1 and a simple 'a'.
The frame also has a child window, which gets the focus and processes the EVT_CHAR events in a OnChar routine.
If I build the code with MSVC 2013 and run it on Windows 7, the behaviour is as I would expect. All three menu accelerators work.
If I build the code on ubuntu 18.04 (in a vm), using gtk3.0.4, the Alt-x and F1 are working, but on pressing the 'a' the corresponding event handler is never hit.

Debugging shows the following :
In the Windows version, when pressing an accelerator key, the event handlers for the EVT_MENU are hit, without passing the OnChar routine.
In the gtk version, the control goes first to the OnChar routine, after this the control is passed through (propagated??) to the event handlers in case of F1 or Alt-x, but never for the single 'a'.

Please advice how this can be fixed in the ubuntu case? Is this expected behaviour? Thanks for taking this into consideration!

Code: Select all

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

#ifndef wxHAS_IMAGES_IN_RESOURCES
    #include "../sample.xpm"
#endif

enum {

ID_TESTING = 101
};

class MyApp : public wxApp
{
public:
    virtual bool OnInit() wxOVERRIDE;
};

class MyCanvas : public wxWindow
{
public:
    // ctor(s)
    MyCanvas   (wxWindow *parent, wxWindowID id);

private:
    // event handlers (these functions should _not_ be virtual)
    void OnChar(wxKeyEvent& event);
    // any class wishing to process wxWidgets events must use this macro
    wxDECLARE_EVENT_TABLE();
};


class MyFrame : public wxFrame
{
public:
    // ctor(s)
    MyFrame(const wxString& title);

    void OnQuit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
    void OnTesting(wxCommandEvent& event) ;

private:
    MyCanvas *m_canvas ;
    
    wxDECLARE_EVENT_TABLE();
};

enum
{
    Minimal_Quit = wxID_EXIT,
    Minimal_About = wxID_ABOUT
};

wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_MENU(Minimal_Quit,  MyFrame::OnQuit)
    EVT_MENU(Minimal_About, MyFrame::OnAbout)
    EVT_MENU(ID_TESTING, MyFrame::OnTesting)
wxEND_EVENT_TABLE()

wxIMPLEMENT_APP(MyApp);


wxBEGIN_EVENT_TABLE(MyCanvas, wxWindow)
    EVT_CHAR(MyCanvas::OnChar)
wxEND_EVENT_TABLE()

MyFrame *frame ;

bool MyApp::OnInit()
{

    if ( !wxApp::OnInit() )
        return false;

    frame = new MyFrame("Minimal wxWidgets App");

    frame->Show(true);

    return true;
}

MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title)
{
    SetIcon(wxICON(sample));

#if wxUSE_MENUS
    // create a menu bar
    wxMenu *fileMenu = new wxMenu;

    // the "About" item should be in the help menu
    wxMenu *helpMenu = new wxMenu;
    helpMenu->Append(Minimal_About, "&About\tF1", "Show about dialog");

    fileMenu->Append(Minimal_Quit, "E&xit\tAlt-X", "Quit this program");

    fileMenu->Append(ID_TESTING, wxT("Testing\ta")) ;

    wxMenuBar *menuBar = new wxMenuBar();
    menuBar->Append(fileMenu, "&File");
    menuBar->Append(helpMenu, "&Help");

    SetMenuBar(menuBar);
#else // !wxUSE_MENUS
#endif // wxUSE_MENUS/!wxUSE_MENUS

#if wxUSE_STATUSBAR
    CreateStatusBar(2);
    SetStatusText("Welcome to wxWidgets!");
#endif // wxUSE_STATUSBAR

    m_canvas = new MyCanvas(this, -1);
    m_canvas->SetFocus();
}

MyCanvas::MyCanvas(wxWindow *parent, wxWindowID id) : wxWindow(parent,id) {

     Bind( wxEVT_MENU, &MyFrame::OnTesting, frame, ID_TESTING );  //adding this or leaving it out does not help
}


void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    fprintf(stderr, "in OnQuit\n") ;
    Close(true);
}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxMessageBox(wxString::Format
                 (
                    "Welcome to %s!\n"
                    "\n"
                    "This is the minimal wxWidgets sample\n"
                    "running under %s.",
                    wxVERSION_STRING,
                    wxGetOsDescription()
                 ),
                 "About wxWidgets minimal sample",
                 wxOK | wxICON_INFORMATION,
                 this);
    fprintf(stderr, "in OnAbout\n") ;
}

void MyFrame::OnTesting(wxCommandEvent& WXUNUSED(event))
{
     fprintf (stderr, "in OnTesting\n");
}

void MyCanvas::OnChar   (wxKeyEvent& event) {

    fprintf(stderr, "in MyCanvas::OnChar\n") ;
    event.Skip();
}
DavidHart
Site Admin
Site Admin
Posts: 4252
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Re: Problem with single char EVT_MENU event on gtk.

Post by DavidHart »

Hi,

That sounds the same or similar to this bug-report.

Regards,

David
oscar1919
Earned a small fee
Earned a small fee
Posts: 17
Joined: Tue Dec 11, 2018 10:40 am
Location: Belgium

Re: Problem with single char EVT_MENU event on gtk.

Post by oscar1919 »

Thanks for pointing this out, David. It really looks like the same issue.
Post Reply