No MouseLeftDown event in wxNotebook empty area Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
sparhawk
Experienced Solver
Experienced Solver
Posts: 78
Joined: Tue May 21, 2013 8:08 am

No MouseLeftDown event in wxNotebook empty area

Post by sparhawk »

I have created a sample app where I capture all mouseevents by binding to the main application event handler, so I can track events independent of the window. This works fine so far, but I wont get any event for a certain area in the wxNotebook.
NoMouseArea.jpg
when I click on any other area like the tabs or inside it, I get the event, but not in the marked area, which is empty, because the notebook has three tabs and they don't extend to the window border.

Any ideas ho I can capture the mouseclick there as well?
User avatar
doublemax
Moderator
Moderator
Posts: 16732
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: No MouseLeftDown event in wxNotebook empty area

Post by doublemax »

I made a test under Windows, and i did receive the mouse click in the notebook's parent.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 5527
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: No MouseLeftDown event in wxNotebook empty area

Post by ONEEYEMAN »

Hi,
What platform and wx version?
Can u post some code reproducing the issue?

Thank you.
sparhawk
Experienced Solver
Experienced Solver
Posts: 78
Joined: Tue May 21, 2013 8:08 am

Re: No MouseLeftDown event in wxNotebook empty area

Post by sparhawk »

This is how I connect the events.

Code: Select all

void wxDockingFrame::BindEventHandlers(void)
{
// We only bind our event handlers for the main frame.
if (gFrames[0] != this)
	return;

wxApp *app = static_cast<wxApp *>(wxApp::GetInstance());

app->Bind(wxEVT_LEFT_DOWN, &wxDockingFrame::OnMouseLeftDown, this);
app->Bind(wxEVT_LEFT_UP, &wxDockingFrame::OnMouseLeftUp, this);
app->Bind(wxEVT_MOTION, &wxDockingFrame::OnMouseMove, this);

app->Bind(wxEVT_SPLITTER_DOUBLECLICKED, &wxDockingFrame::OnSplitterDClick, this);

app->Bind(wxEVT_SIZE, &wxDockingFrame::OnSize, this);
app->Bind(wxEVT_SIZING, &wxDockingFrame::OnSize, this);
}
Full source can be found here: https://github.com/skeetor/wxWidgets/tree/development (note the branch).
If you want to build it, you have to build my wxWidgets fork first https://github.com/skeetor/wxWidgets/bl ... wx_vc9.sln. There is only a minor change there that I require, which is not related to this problem as I had this problem also before I made that change.
Then you can build the application: https://github.com/skeetor/wxWidgets/tr ... es/docking

wxDockingFrame is directly derived from wxFrame and the event handlers are bound first thing in the constructor.

My fork is about a year old, so I try to move it to the latest master. I will give that a try as well.
User avatar
doublemax
Moderator
Moderator
Posts: 16732
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: No MouseLeftDown event in wxNotebook empty area

Post by doublemax »

I'm very surprised your approach works at all, you shouldn't be able to receive these events that way. If you want to catch all events at wxApp level, use wxAppConsole::FilterEvent
https://docs.wxwidgets.org/trunk/classw ... c6f602e20c

This is the code i used for testing (add at the end of MyFrame ctor of the "minimal" sample):

Code: Select all

wxNotebook *nb = new wxNotebook(this, wxID_ANY);
nb->SetBackgroundColour(*wxYELLOW);

wxPanel *redpanel = new wxPanel(nb);
redpanel->SetBackgroundColour(*wxRED);
nb->AddPage(redpanel, "red");

wxPanel *greenpanel = new wxPanel(nb);
greenpanel->SetBackgroundColour(*wxGREEN);
nb->AddPage(greenpanel, "green");

this->Bind(wxEVT_LEFT_DOWN, [=](wxMouseEvent &evt) {
    wxLogDebug("frame mouse left down");
    evt.Skip();
});

this->Bind(wxEVT_LEFT_UP, [=](wxMouseEvent &evt) {
    wxLogDebug("frame mouse left up");
    evt.Skip();
});
Use the source, Luke!
sparhawk
Experienced Solver
Experienced Solver
Posts: 78
Joined: Tue May 21, 2013 8:08 am

Re: No MouseLeftDown event in wxNotebook empty area

Post by sparhawk »

Cool! Thanks for the info. I tried it now with that event filter and it works. :) So should I rather use the event filter not Bind?

Since the event filter is now an external class, I have to call the handlers directly from inside the eventfilter, right?

Something like this:

Code: Select all

int FilterEvent(wxEvent &event)
{
   if(leftDown)
       frame->OnMouseLeftDown(event);
}
Or would this cause some unwanted side effects? Do I still have to call event.Skip()/Veto() or do I handle this via the returncode only?

Actually, when I started this project, I was looking for some info on how to connect to all events,and I only found that Bind method for it. This looks much better though.
User avatar
doublemax
Moderator
Moderator
Posts: 16732
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: No MouseLeftDown event in wxNotebook empty area

Post by doublemax »

sparhawk wrote: Fri Jan 14, 2022 10:21 pm Since the event filter is now an external class...
Not necessarily. You can also override wxConsoleApp::FilterEvent()

Code: Select all

int MyApp::FilterEvent(wxEvent &event)
{
  const wxEventType t = event.GetEventType();
  // do your stuff here

  return Event_Skip;
}
However, this is normally only used for global events or for debugging. And it seems unrelated to our initial question. So i'm not sure if it's the right tool for your job.
Use the source, Luke!
sparhawk
Experienced Solver
Experienced Solver
Posts: 78
Joined: Tue May 21, 2013 8:08 am

Re: No MouseLeftDown event in wxNotebook empty area

Post by sparhawk »

I have created now a seperate class derived from EventFilter, as this was also described in the document link. Works like a charm, and it solved a big problem. Because in my docking code I couldn't move wxNotebooks, because of this problem and this works now. :D

I was wondering why you always said I should connect to wxConsoleApp, because I was not starting from wxConsoleApp but wxApp instead. However, I connected my filter like this

Code: Select all

	wxApp *app = static_cast<wxApp *>(wxApp::GetInstance());
	if (!gEventFilter)
		gEventFilter = new wxDockingEventFilter();

	app->AddFilter(gEventFilter);
Is there a reason for insisting on wxConsoleApp or is this just out of habit? AFAIK when I use a wxConsoleApp, I will get a console window in Windows, right? Which I sure don't want. :)
Last edited by sparhawk on Fri Jan 14, 2022 10:57 pm, edited 2 times in total.
User avatar
doublemax
Moderator
Moderator
Posts: 16732
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: No MouseLeftDown event in wxNotebook empty area

Post by doublemax »

When you look at the class hierarchy for wxApp, you'll see that it derives from wxAppConsole. I only kept saying wxAppConsole, because that's where FilterEvent() is declared.

https://docs.wxwidgets.org/trunk/classw ... nsole.html
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 3250
Joined: Sun Jan 03, 2010 5:45 pm

Re: No MouseLeftDown event in wxNotebook empty area

Post by PB »

sparhawk wrote: Fri Jan 14, 2022 10:50 pm I was wondering why you always said I should connect to wxConsoleApp, because I was not starting from wxConsoleApp but wxApp instead. However, I connected my filter like this

Code: Select all

	wxApp *app = static_cast<wxApp *>(wxApp::GetInstance());
Why not just use wxGetApp(), assuming you used wxIMPLEMENT_APP()? This will get you a reference to the actual derived class of your application.

There is also wxTheApp global variable...
sparhawk
Experienced Solver
Experienced Solver
Posts: 78
Joined: Tue May 21, 2013 8:08 am

Re: No MouseLeftDown event in wxNotebook empty area

Post by sparhawk »

However, this is normally only used for global events or for debugging. And it seems unrelated to our initial question. So i'm not sure if it's the right tool for your job.
I thought that I should use such an approach, because I'm writing an extension for wxWidgets. A proper docking module as a replacement for wxAUI classes, which have certain problems that I can't work around or fix (I tried). So I need to get those events regardless of which window is used, and AFAIK I can't do this in some other way, or is there something I missed? I thought that some client code might be able to steal some events depending on the order of processing or not getting events at all for child windows when connecting them the normal way. Which seems already to be the case as for the notebook.
PB wrote: Fri Jan 14, 2022 10:56 pm Why not just use wxGetApp(), assuming you used wxIMPLEMENT_APP()? This will get you a reference to the actual derived class of your application.

There is also wxTheApp global variable...
My code will be an extension for wxWidgets and is part of the library itself. Not sure if I can rely on such a global variable.
User avatar
doublemax
Moderator
Moderator
Posts: 16732
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: No MouseLeftDown event in wxNotebook empty area

Post by doublemax »

...because I'm writing an extension for wxWidgets
One more reason for not using an ugly hack. Every single event in the application passes through this function, and that's many. And like i said before, it's unnecessary, because you do receive the click into the empty area of the notebook tabs in its parent (at least under Windows).
Use the source, Luke!
sparhawk
Experienced Solver
Experienced Solver
Posts: 78
Joined: Tue May 21, 2013 8:08 am

Re: No MouseLeftDown event in wxNotebook empty area

Post by sparhawk »

doublemax wrote: Fri Jan 14, 2022 11:10 pm
...because I'm writing an extension for wxWidgets
One more reason for not using an ugly hack. Every single event in the application passes through this function, and that's many. And like i said before, it's unnecessary, because you do receive the click into the empty area of the notebook tabs in its parent (at least under Windows).
Receiving this event on that empty area was not working before. Also, this was only a part of the events I need, as I need to be able to monitor those events on any window that a user has created. When I connect the events to my frame,as it is normally done, I wont receive events when the user creates child windows, right? So when there is a button near the area where the docking should be started, and the user clicks and drags on it, the button will receive those events and I wont get them if I understand it right.
Post Reply