Skip to content

Adding items to a list inside a timer sometimes results in "BUG" console warnings #118

Description

@halfer

I have some wxPHP code that results in console warnings. There does not seem to be any major impact on the GUI side, as far as I can tell. The error is thus:

*** BUG ***
In pixman_region32_init_rect: Invalid rectangle passed
Set a breakpoint on '_pixman_log_error' to debug

I have written a script to reproduce this, and find that with 10 list operations, there is a chance that the error will not be displayed - running the script five times may result in warnings on one or two occasions. I therefore suspect some kind of race condition.

Here is the script:

<?php

/**
 * Demo of refresh bug in list controls when amending them from a timer:
 *
 *      *** BUG ***
 *      In pixman_region32_init_rect: Invalid rectangle passed
 *      Set a breakpoint on '_pixman_log_error' to debug
 *
 * Does not help:
 *
 * - Creating the timer after the window is shown
 * - Letting the first timer event do nothing
 * - Disable the list control whilst it is being updated
 * - Refresh control after each change
 * - Disable or freeze control during changes
 *
 * This works:
 *
 * - Make control invisible whilst it is being updated
 */

// Create main window
$frame = new BackgroundPopulationFrame();
$frame->Show();

wxEntry();


class BackgroundPopulationFrame extends \wxFrame
{
    const FIX_BUG = false;
    // The bug seems to be subject to race conditions, so increase
    // this if you don't see warnings in the console
    const LOOP_COUNT = 10;

    protected $list;
    protected $timer;

    public function __construct($parent = null)
    {
        // Create a main window
        parent::__construct($parent, wxID_TOP, "Title");

        // Create a list control
        $this->list = new \wxListCtrl($this, wxID_ANY);
        $this->list->SetWindowStyleFlag(wxLC_REPORT);
        $this->list->InsertColumn(0, "Title");

        // Place window in centre of the screen
        $this->Centre(wxBOTH);

        // Start the background population
        $this->startPopulateTimer();
    }

    /**
     * Call a timer device to populate the list box
     */
    protected function startPopulateTimer()
    {
        $this->timer = new \wxTimer($this);
        $this->Connect(wxEVT_TIMER, array($this, "onTimer"));
        $this->timer->Start(50);
    }

    public function onTimer()
    {
        if (self::FIX_BUG)
        {
            #$this->list->Disable(); // Doesn't work
            #$this->list->Freeze(); // Doesn't work
            $this->list->Hide(); // Works but will be rather confusing for it to disappear
        }

        for($i = 0; $i < self::LOOP_COUNT; $i++)
        {
            $this->list->InsertItem($this->createCell($i, 0, "Title " . $i));
            #$this->list->Refresh(); // Doesn't work
        }

        $this->timer->Stop();

        if (self::FIX_BUG)
        {
            #$this->list->Enable(); // Doesn't work
            #$this->list->Thaw(); // Doesn't work
            $this->list->Show();
        }
    }

    protected function createCell($row, $column, $name)
    {
        $item = new \wxListItem();
        $item->SetId($row);
        $item->SetColumn($column);
        $item->SetText($name);

        return $item;
    }
}

My use case is to use a timer device to carry out long-running operations in pieces when a timer control fires. Using threads may be more appropriate for this, but (a) I didn't have much luck with using them, and (b) in my view this exposes a bug that needs addressing. I think I will continue to investigate the timer approach and tolerate the warnings for now.

I've discovered that hiding the list control during the timer operation and then re-showing it removes the warnings very reliably. Sadly freeze/thaw did not have the same effect - that would have caused a lot less screen disruption.

Tested on PHP 5.5.9-1ubuntu4.14 on Ubuntu 14.04 LTS.

Activity

  1. halfer commented on Dec 6, 2015

    @halfer
    ContributorAuthor

    I also tried using a single timer to wait for the list to appear on screen (wait one second and then stop immediately) and then using another timer for the periodic list box population. This did not fix the problem entirely, though it did seem to occur a bit less.

    I've found show/hide to introduce some flicker in the control, depending on the timer frequency. My solution for the time being is to hide the control until it is fully populated by repeated timer calls.

  2. changed the title [-]Adding items to a list inside a timer sometimes results in "BUG" warnings[/-] [+]Adding items to a list inside a timer sometimes results in "BUG" console warnings[/+] on Dec 6, 2015
  3. halfer commented on Dec 7, 2015

    @halfer
    ContributorAuthor

    I wonder if this is quite a common problem. Running the grid.php example just now produces this output:

    /usr/bin/php -d extension=wxwidgets.so grid.php 
    string(6) "Ubuntu"
    *** BUG ***
    In pixman_region32_init_rect: Invalid rectangle passed
    Set a breakpoint on '_pixman_log_error' to debug
    

    The string is a var_dump() output, and some GUI operation will have created the *** BUG *** output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions