Zeno's Notes

...

7 notes

Fixing an “Easy” Padre Bug, Step By Step

Today I want to describe how I fixed a rather simple bug in Padre. I share this experience in detail mostly because I want to motivate other people to help improving Padre’s codebase. While there is plenty to be done, starting to hack Padre can be a bit intimidating because of the rather large and complex codebase.

Warning: Perl code and some Padre internals ahead … if you are not a programmer, this post will most likely be very boring for you.

This article is inspired by an older blog post by Sewi, who also described how he debugged Padre.

First of all, for Padre development you should run the trunk version from the subversion repository.

During the testing of the upcoming release, I came across a small bug that had already been reported a while ago.

The bug was about where the input focus goes when you double click in different parts of the side panel:

  • For the function and the TODO list, not only the view should change to the function definition in the file, but also the input focus should go to the editor window.
  • This works correctly if you double click on files in the project browser, but the editor loses focus if you double click on a directory.
  • The outline view behaves how it should.

My initial assumption was that there must be something in the outline code that sets the focus, which seems to be missing in the other parts. Thus my strategy to tackle this bug was to find this (hopefully tiny) piece of code and add it where it is missing.

The code for the outline view is in Padre::Wx::Outline. Searching for “focus” led me to this line in the method select_line_in_editor:

$editor->SetFocus;

First, I tried to fix this in Padre::Wx::FunctionList (hint: you can quickly access files in the same project with Ctrl-Shift-R). There I search for the statement that was preceeding SetFocus: $editor->goto_pos_centerize. I find it and add $editor->SetFocus; after it.

Then I run Padre’s dev script, which takes into account changes in the source tree without requiring a new installation, to check whether the changes really fixed the bug in the function list.

And what happens? It turns out that this fix does not work. After further playing around, and fixing other issues on the way, I realized that even the SetFocus is not necessary, because goto_pos_centerize already calls SetFocus. I fixed that in the outline code.

The outline, TODO, and function views now behave better than before, or at least have some simplified code, but we still have no progress with our initial problem …

We know that SetFocus is called, so that cannot be the problem. Next assumption: Maybe the SetFocus action is somehow undone by something that happens afterwards? As a first test of this assumption, I added a small pause to the end of goto_pos_centerize in Padre::Wx::Editor:

$self->Update;
sleep 5;

This should allow us to see more clearly what happens. What we see confirms our assumption: The focus is in the editor for 5 seconds.

Now we need to find out what causes the change after the focus was already set. The WxWidgets documentation should contain all relevant information for that. The function list inherits from Wx::Panel (wxPanel in C++), and uses a Wx::ListBox (wxListBox) so this is the place to start looking. But no luck here, not much about event handling. Next stop: The description of event handling in Wx::Perl. In particular we are interested which handlers are called. As I could not find this out from the documentation, I took the event list from the Wx::Perl wiki and checked for all kinds of different events:

   Wx::Event::EVT_LEFT_DCLICK(
      $self,
      sub {
         my ( $this, $event ) = @_;
         warn "Panel EVT_LEFT_DCLICK handler\n";
         return;
      }
   );   
   Wx::Event::EVT_SET_FOCUS(
      $self,
      sub {
         my ( $this, $event ) = @_;
         warn "Panel EVT_SET_FOCUS handler\n";
         return;
      }
   );   
   Wx::Event::EVT_KILL_FOCUS(
      $self,
      sub {
         my ( $this, $event ) = @_;
         warn "Panel EVT_KILL_FOCUS handler\n";
         return;
      }
   );   
   Wx::Event::EVT_CHILD_FOCUS(
      $self,
      sub {
         my ( $this, $event ) = @_;
         warn "Panel EVT_CHILD_FOCUS handler\n";
         return;
      }
   );   

   # Double click on list ...
   Wx::Event::EVT_LEFT_DCLICK(
      $self->{list},
      sub {
         my ( $this, $event ) = @_;
         warn "EVT_LEFT_DCLICK handler\n";
         return;
      }
   );   
   Wx::Event::EVT_SET_FOCUS(
      $self->{list},
      sub {
         my ( $this, $event ) = @_;
         warn "EVT_SET_FOCUS handler\n";
         return;
      }
   );   
   Wx::Event::EVT_KILL_FOCUS(
      $self->{list},
      sub {
         my ( $this, $event ) = @_;
         warn "EVT_KILL_FOCUS handler\n";
         return;
      }
   );   
   Wx::Event::EVT_CHILD_FOCUS(
      $self->{list},
      sub {
         my ( $this, $event ) = @_;
         warn "EVT_CHILD_FOCUS handler\n";
         return;
      }
   );   

OK, that is not very elegant, but in the end it did the job: I found out that the default handler EVT_LEFT_DCLICK is responsible for stealing the focus. All we need to do is to overwrite this handler:

   Wx::Event::EVT_LEFT_DCLICK(
      $self->{list},
      sub { return; }
   );

After adding this event handler to the TODO and the function lists, all that remains to do is to stress-test the new implementation a bit to check whether there are no newly introduced bugs, run ../tools/tidy_project.pl, edit the Changes file, and commit it to the Padre subversion repository:

svn commit -m "fix #967: reset focus" Changes lib/Padre/Wx/FunctionList.pm lib/Padre/Wx/TodoList.pm

Finally, I can close the corresponding ticket in Trac: "Fixed in r13759."

Easy, wasn’t it? Although it took a little bit longer than expected, I hope you enjoyed it. As already said, there are many more small bugs looking for fixes, and it is not that hard. Plus you get to know Padre’s codebase, which will enable you to even contribute additional features.

If you have questions regarding the development of Padre, don’t hesitate to ask in our IRC channel or on the mailing list.

Filed under padre perl ide editor modern perl

  1. lewesde reblogged this from zenoga
  2. zenoga posted this