Neil's Place

January 14, 2013

So What’s Up With That Strange Focus Model on Mac?

Filed under: Mozilla — enndeakin @ 8:45 pm

This is a question that comes up a lot from other people when you are somebody that is expected to investigate and fix focus related Firefox bugs. People are confused as to why Mac has such an unusual way of handling of focus. The questions and confusion can usually be summarized as follows:

This Macintosh doesn’t behave exactly the same as the Windows (or Linux) machine I’ve been using for years does! It must be wrong!

Now I don’t know the actual reasoning as to why Apple might have chosen the particular focus behaviour they did, not for that matter why Microsoft, or any other platform vendor might have chosen the behaviour they did, but I can make some guesses.

On Windows, it is expected that a user uses both the mouse and the keyboard to interact with the user interface. The user is expected to only be interacting with one control at a time. If the user starts to interact with a control with the mouse, it is expected that the user, when then using the keyboard, will want to interact with that same control. There are exceptions however, for example, buttons on certain toolbars. Assuming this, Windows will move the focus to a control when you click on it.

The Macintosh however assumes that most people who are using a mouse aren’t going to interact with controls with the keyboard if they don’t need to. For instance, while you could toggle a checkbox by tabbing to it and pressing the space bar, most people don’t do this. Thus, the focus is only placed on those controls where one must use the keyboard to interact with it, or those where keyboard interaction is quite common. This means, text entry fields and list boxes. For text fields you need to be able to type in them and perhaps people commonly change items with the cursor keys in lists (or perhaps because you cannot select multiple non-contiguous items in a list without holding a key down) Thus, on Mac, clicking on any other control that isn’t a text field or list keeps the keyboard focus where it is rather than changing it.

For most typical users, it is quite handy to only have textboxes (and lists) in the tab navigation order. For example, when entering a login and password or other personal information, you can cycle between only those fields where you enter text, rather than having to skip over the various other buttons and links that might appear nearby. In addition, you can click the ‘Remember this Password’ checkbox and continue entering the password. On Windows, you would need to click the password field again. You can always set the ‘Full Keyboard Access’ setting to make all controls part of the tab navigation sequence.

Modern versions of Windows don’t show focus indicators (the dotted rings) around controls until the keyboard is used to navigate within a window, for example by pressing Tab or an access key. There’s a system setting that can always enable focus indicators. In addition, older versions of Windows that didn’t have this setting will always show focus indicators. Actually, there’s one, almost secret, way to show focus indicators by default and that is to open a dialog box by using the keyboard instead of the mouse. What heuristics Windows uses to determines this is unclear, but you can see the effect for yourself by opening the Properties dialog for a file. When using the mouse alone the focus indicator doesn’t appear on a control, whereas if you navigated the menu and selected Properties using the cursor keys and Enter, the focus indicator does appear on a control in the resulting dialog. This little known feature works in Firefox too! (Or it would if the main menu wasn’t so broken.)


Here’s one! The focus ring has appeared around the button.

Because Macintosh doesn’t focus most controls when clicking them, you rarely see the blue glowing focus rings around them. However, if one was to focus, for example, a button manually using code, the focus ring will appear around it. You can see this if you look around the Mac OS X UI a bit, even without using the keyboard at all.

Here is a rough guide to how the focus is expected to behave within Firefox across the three main platforms.

Advertisements

September 21, 2012

Status Update of Happenstance

Filed under: Mozilla, Status Updates — enndeakin @ 9:25 pm

I decided to work on two bugs today. The first is bug 792296 to reduce the number of reflows that happen when calling various popup methods. The other is bug 621944 which causes wrapping around to the start of the message when finding text in Thunderbird to fail to function properly. Both bugs are completely unrelated and involved changing very different parts of code.

The first bug was simple. Just change a couple places where a flush is done so as to not flush and get the frames for the popup directly. Test and then submit to the tryserver.

While that is happening, investigate the review comments from the second bug which clued me in as to what was wrong. The simple fix here is that the wrong window was being used to start the text search; instead of using the focused child frame of the window to find in, the focused child frame of the active window was being used. Write a patch and local testing shows that it fixes the problem in Thunderbird, and also fixes a simple testcase.

Some tryserver results from the first bug are now available, showing that there are failures in some private browsing and network tests. Odd, those tests aren’t using popups and look unrelated. It fails on every machine so doesn’t look like an intermittent failure. No one else’s builds show the error, so this is strange.

Run the failing tests locally. They work fine. Scratch head. Run a larger batch of tests. They still work fine. Consider making Ehsan fix the problem. Nope, he’s eating lunch.

After a while I discover an amazing thing. I don’t get the test failures locally because they are fixed by the patch to the second bug! By sheer coincidence, the patches to two unrelated bugs come together to fix both bugs! And that’s not all! It looks like it’s intermittent orange bug 707599! Fixed! Fixed! Fixed!

Also today: bug 793157 which adds a moveToAnchor method to popups and panels to allow one to move an open popup to a particular anchor location.

March 30, 2012

XBL Forward

Filed under: Mozilla — enndeakin @ 4:50 pm

I’ve been working on investigating what it would take to make some improvements to XBL, either by implementing XBL 2 or something else. My motivation here is to improve the XUL widgets so that are easier to use, stabler and faster. I gave a talk at Fosdem outlining the various forms of XBL at present and possible routes forward in the future. There are three possible ways forward.

The first option is to implement the XBL 2 specification as is. There are two versions of this specification, the original one, created in 2007, and a newer version, created in 2010, that removes a number of features.

The advantages of this approach:

  • Already has a complete specification that underwent some design already.
  • To some degree, it builds on top of the existing XBL, so we may be able to build some features incrementally.

Disadvantages:

  • As no other browser has implemented or attempted to implement it, there isn’t any reason to implement it as is.
  • For internal use, a specification can restrict certain extended features that will be needed. These include connecting to native components as well as accessibility.

Approach two involves a set of new features being designed by Google, under the umbrella term Web Components.

Advantages:

  • The design here is broken into several smaller features, rather than having one large feature. This may make doing the implementation in stages easier.
  • Since Google is already working on this, it is likely an easier route to multiple compatible implementations.

Disadvantages:

  • The features described aren’t necessarily better design, just different, and likely don’t encompass all of the design issues we’ve experienced.

A third approach is to take the existing XBL implementation, and simply improve the features that we don’t think are working as well, and enhance or replace those parts with implementations that are more robust, offer better performance and are easier to use. In addition, new features would be added to address shortcomings, generally from the XBL 2 specification or otherwise where they are useful.

Advantages:

  • Likely easier to implement, as it builds on top of an existing implementation.
  • It has no constraints on others to design or agree on a specification, so features can be designed to fit our needs

Disadvantages:

  • The main disadvantage is that is use would be limited to Mozilla’s own use internally.

I’ve spent much time over the last few months trying to determine which approach is best.

XBL belongs to a larger class of application that is attempting to allow for component creation, abstract representation and general templating mechanism. There are many tools and libraries available both running on a client and a server that attempt to provide these types of features. XBL attempts to solve specific use cases, but doesn’t attempt to solve others. One way to design XBL would be to allow it to solve the more complete set of component and template generation features.

For example, the documents for Web Components describe some examples of templating, which XBL doesn’t address directly. Although it doesn’t specify a syntax, it gives an example containing a tag written as: <li class=”${importance}”>. This implies that some form of value substitution is desired. XBL only provides attribute substitution in a limited form. Does this mean that XBL should be extended to allow a more sophisticated template mechanism to allow the markup structure to be changed in more powerful ways?

Naturally, the more features added, the more complicated the implementation will become. More importantly, it becomes much more difficult for multiple implementations or their users to agree on a common syntax. Indeed, the presence of Web Components and multiple XBL specifications implies that such agreement is difficult. Another example of this is persistent storage in a browser. Several variants have been proposed and/or implemented, including a key/value storage mechanism (localStorage), an SQL database syntax, and IndexedDB. There are probably others, and some use cases are not covered by all of these. Do we simply choose one or some of these and ignore the remaining use cases?

Mozilla hasn’t shown any interest in implementing XBL 2, and neither have any other browsers. So it seems to me that XBL is one of those areas where having a specification hasn’t served much purpose.

If I were implementing the future of XBL today I would favour approach three that will get useful functionality implemented faster. This is for several reasons, one, is that I don’t feel that consensus on anything beyond a basic set of features will happen any time soon, or at all. Two, spending extensive amounts of energy working on trying to create and/or expand on some form of multi-vendor specification isn’t interesting to me, as I don’t care about web development. Third, since I’m talking about what I would do if I were implementing it, it’s the simplest way to improve the XUL UI widgets we have.

I wrote the start of a feature page.

November 3, 2011

Window Reflows on Startup

Filed under: Mozilla — enndeakin @ 2:02 pm

I took a look at what happens on Firefox startup on Mac with a profile I’ve used for testing for a while. Specifically, how often and why the root element (<window>) in the browser window is asked to be laid out. Each line below is an attempt to lay out (reflow) the root element. A reflow can happen as a result of a number of different things such as new elements being inserted, images being loaded and so forth. What happens is that the document layout objects are marked as dirty as necessary, then at a future point, a reflow occurs. This allows a script to make a number of changes without having each change cause a full refresh. I’ve broken down each attempt to mark the root element (or some other reflow root) as dirty, separated by commas in each line. In the table below, a reflow occurs 15 times.

Action

Time to finish
Hidden Window

0.55ms

Main Window is parsed and laid out

14.95ms

Attribute changed, and loaded page (about:blank) is laid out

0.78ms

Search icon is set

0.35ms

Scrollbar attributes changed, toolbarspring is inserted, window’s load event fires and listeners called and finished

2.21.ms

Scrollbar attributes changed, tabview.png is set

0.34ms

folderDropArrow.png is set

0.27ms

browser.js delayedStartup() is called, splitter is inserted into urlbar

0.24ms

menupopup is appended to back button, delayedStartup() finishes, bookmarks toolbar handling begins

5.77ms

chrome://browser/skin/places/query.png is set

0.56ms

chrome://browser/skin/page-livemarks.png is set

0.39ms

chrome://global/skin/tree/folder.png is set

0.46ms

Call to flush frames

0.33ms

Bookmark icon is set

0.48ms

Bookmark icon is set

0.37ms

The last few images are all the assignment of the icons on the bookmarks toolbar. These don’t occur if the toolbar is hidden. In total, approximately 400 changes to an element’s attribute are made and 41 nodes are appended to the document after it is parsed.

Now let’s take a look at the mobile version, running on an Android tablet. Here, 24 reflows occur over the 2200ms startup time.

Action

Time to finish
Insert html element into main window?, insert html element into hidden window?, parse and lay out main window

7.43ms (also 183.7ms reading xbl)

Four dirty marks caused by scrollbar attribute changes

1.07ms

Remove text node (a <br> is appended to a <div> immediately following), append <documenttab>

2.55ms

Append <notificationbox>

0.78ms

Some attributes on <label> and <image> elements are changed, some <label> elements are removed

1.20ms

scrollbar.pageincrement is changed

0.28ms

SizeToContent is called

0.22ms

Unknown reason, but probably caused by bug 230959

0.94ms

slider.pageincrement is changed, attributes on <tablet> are changed

5.329ms

Three dirty marks caused by scrollbar attribute changes

1.65ms

Attribute changed on a <scrollbox>

1.19ms

Attribute changed on a <scrollbox>

0.57ms

Attributes left, width and height changed on a <vbox>

1.40ms

Two scrollbar related dirty marks, mode attribute changed on various things (no dirty mark), loading attribute on an <image>

1.88ms

mode attribute changed on various things (no dirty mark), loading attribute on an <image>

0.76ms

Some <image> elements are inserted and removed

0.72ms

Unknown reason, probably a flush caused by retrieving some layout information

0.53ms

Unknown reason, probably a flush caused by retrieving some layout information

0.68ms

Loaded page starts appearing, <toolbarbutton> label changed

2.27ms

Text node appended to page

0.51ms

Text node removed from page, height changed on an <hbox> related to a nearby <canvas>.

1.54ms

mode attribute changed on various things (no dirty mark), loading attribute on an <image>

0.74ms

<box> is marked not hidden (think this is the autocomplete widget), insert frames into box, some attributes on <richlistitem> and <menuitem> are changed

33.78ms (also 265.18ms reading xbl)

Eight dirty marks caused by scrollbar attribute changes

2.70ms

Observations:

  • There are lots of changes to scrollbars here, despite no scrollbars on mobile Firefox being visible. The set listed in the last row is likely caused by the resize caused by the on-screen keyboard appearing. 120ms of time occurs from when this begins to when this ends, although it is likely that only a small amount of this is directly scrollbar related.
  • I didn’t measure XBL parsing time on desktop Firefox in this test, but it typically takes about 10% of the startup time. Of course, XBL caching should reduce the time to load XBL here. It should be noted though that parsing and creating the main document takes 25% of the rest of the time.
  • The time between reflow 2 and reflow 18 is 550ms. I’m not familiar enough with the mobile code, but this appears to be the time to process and manipulate things after the main document is parsed, equivalent to desktop Firefox’s handling in browser.js.
  • The last two rows are for the autocomplete and on-screen keyboard appearing. It takes up 675ms of time, but the main window has already appeared, so the user’s perception of the time to start up may not need to include this time.

October 4, 2011

XBL Performance Tips

Filed under: Mozilla — enndeakin @ 5:13 pm

As I’ve been investigating XBL caching, I’ve been looking into some additional performance characteristics. Here are some tips on improving your use of XBL in Mozilla, relying on specific implementation details to gain performance benefits. You probably won’t notice much difference, but lots of minor changes can add up.

Properties and methods, that is the code in <property> and method <body> elements are compiled once per session. The code is compiled once when the first element that uses the binding is added into a document. For elements included in a XUL document, this means that they will be compiled while the window is being created and opened. Constructors and destructors are treated similarly.

Fields and handlers (<field> and <handler> elements) however are not compiled when the element is added. Instead, they are compiled on demand when they are used. This means that both fields and handlers do not directly affect the time to open a window, but can instead, in the case of handlers, affect the time to respond to an event.

Fields

The field element defines a value on a element. The code for it is compiled when the field is first accessed, not when it is defined. For example, assume a field exists such as that below:

 <field name="someValue">10 * 50</field>

The code ’10 * 50′ will be compiled and evaluated when code that checks ‘element.someValue’ is encountered. Naturally, if this happens during the binding constructor, this will affect creation time. Although I haven’t investigated this, if this is the case, it might be better to just initialize the field directly in the constructor to save the overhead of having to evaluate the field separately.

However, for fields that are rarely accessed, initialization within the field itself is generally more optimal.

A very important note however, is that the field value is compiled and evaluated not once per session or even once per window. The code in a field body is compiled and evaluated once for every element that uses it. Sometimes, people write large blocks of initialization code directly in the field element. If this field isn’t accessed often, or the binding is only used once or twice in a window, this won’t matter too much. But if the binding is used frequently, this can have notable impact on performance. Instead, call a method from the field initializer such that at least the compilation is only performed once.

It also goes without saying that enumerating an object with a binding will invoke all of the fields and evaluate all of their code.

Handlers

Event handlers defined in XBL are compiled the first time the event occurs. So, for example, a handler for a keydown event will get compiled when the element is focused and a key is pressed down. This saves time when creating the element for rarely used event handlers.

Unlike fields, handlers are only compiled once per window, even when multiple elements exist within the same window. This means that putting all of your code in a method and having handlers that simply wrap the method requires more time to create as methods are compiled when created. If improved creation or startup time is more important to you, then place the code in the handler instead.

It helps to use the event filtering attributes on the <handler> element when possible. These will filter out events that aren’t what the handler code is interested in, and avoids the need to compile and call the script code at all, as these filters are implemented entirely in native code. Attributes for filtering available include: modifiers, button, clickcount, keycode, charcode, and phase.

The description above mainly applies to compile time of the various XBL parts. In all cases, for fields, properties, methods and handlers, the compiled code must still be attached to the content each time the binding is used.

In summary, the choice of how to structure the specific parts of the XBL depends on where better performance is needed.

The display and extends attributes

This isn’t a entirely a performance tip but sometimes the display attribute (or the extends attribute) on a binding is used when it doesn’t need to be, for example:

 <binding extends="xul:box"> 

This particular example doesn’t generally do anything for XUL elements as they are already boxes. The example above might do something if you had changed the display type in a some other manner, but that is a very rare occurrence. The colon-form syntax used here does not mean that it extends some other binding or element. In fact, where it does have a use doesn’t relate to XBL at all. Instead, it specifies which internal layout objects get created for the element.

Although in the past any element could be used for the display/extends colon-syntax, today there are only sixteen tags that are allowed, only half of which are actually useful. (The list of tags to allow was generated by searching the Mozilla source for usage rather than fixing up the cases where it was used and wasn’t necessary).

One such tag that might be worth investigating for performance is using display=”xul:spacer” on a binding. It creates a layout object that will never have children. If you know your binding will have no children, either regular or anonymous, it saves a very tiny amount of extra time and storage (60 bytes or so per element).

Many specific additional tips could be made but it is hard to measure the exact benefit in many cases. I’ve investigated some cases with xbl inheritance, but haven’t found any specific tips there yet. I’m continuing to look into other areas.

July 17, 2011

Status Report for July 17

Filed under: Mozilla, Status Updates — enndeakin @ 7:48 pm

This week I mainly did two things:

  • Made a few minor changes to the patch to handle using popups as drag feedback, to simplify the code.
  • Posted patches to store and read XBL bindings to the startup cache. This is a work in progress, but I spent this week getting the patches to the point where they don’t cause any test failures. There is still some work to be done: various warnings occur when reading the bindings, error handling needs to be improved, there may be a minor memory leak to investigate and, for whatever reason, the cache is only read the second time rather than the first time it is available. The latter is some remnant of the switch to using a startup cache, which stores the cached data in a zip file, rather than the specialized format fastload file.

July 8, 2011

Status Update for July 8

Filed under: Mozilla, Status Updates — enndeakin @ 8:14 pm

This week I mostly finished off a patch to handle panels as drag feedback images. Currently, when dragging, a feedback image is created from the element being dragged, or a script may change the feedback image with the setDragImage function. However, the image is always a static image. With this patch, if you pass a <panel> element to the setDragImage function, the panel will be used directly as the drag feedback, allowing the feedback image to be changed while dragging.

This will allow you to not only change the content and appearance of the drag feedback image while the drag is occurring, but also the position and size. This should allow for some interesting drag effects.

The only other step besides using the setDragImage function, is to ensure that you set type=”drag” on the <panel> element. This ensures that the popup behaves as a drag feedback image. Otherwise, drag events will get fired on the panel itself, and you will likely want them to be ignored and instead fired on what you are dragging over underneath the panel.

See bug 533460 for more details. Some builds are also available with these feature.

Some other things I have done recently:

  • Put up a some updated patches for clipboard event handling.
  • Fixed some elements such as the datepicker and tree such that they cancel mouse scroll events and key events properly
  • An issue where dropping on plugins was not allowed.
  • Some cleanup of xul headers.
  • Changed xml-datasource template generation so that the ids from the source document are used. This allows persistence to work properly.

April 4, 2011

Loading XBL Performance

Filed under: Mozilla — enndeakin @ 3:56 pm

A while ago I spent a bit of time looking at the performance of opening a new window recently. My first few experiments were actually a bit off track as I realized that I had my XUL cache disabled. This isn’t representative of most users, so isn’t completely valid for testing real performance, but it did get me thinking a bit.

In case you’re wondering, the XUL cache does two things. When a XUL file is loaded, it is parsed into an in-memory form and the scripts compiled into a bytecode-like form. When that file is needed again, the already parsed and compiled form is used instead of reading it again. The second step is that the parsed form is saved out to disk in a file. When the browser is restarted, this file is read instead. This way, the source form is not reparsed each time. This process happens for both XUL content and for Javascript. Instead of compiling the script into bytecode each time, the bytecode is serialized to disk and reused the next time. This process improves performance significantly at the cost of a couple of megabytes of disk space.

The file the parsed data is stored in, generally called the fastload file, is currently located in the same place as the network cache and can be found with the filename XUL.mfasl. You can safely delete it and it will get recreated when you start the browser again if you want to see how it affects startup time. (although that test will of course be affected by the time it takes to write it out again).

With the cache disabled, none of the above happens and the files must be reread from the source every time. However, when I had the cache disabled, I noticed that a significant amount of time was taken up by compiling the script associated with XBL bindings. Much less time was used with the cache enabled again.

Now, one thing of note here, is that, unlike XUL documents, only one part of the cache mechanism is used for XBL. XBL is only cached in memory and it isn’t saved out to the fastload file on disk. This means that this compilation time occurs upon each startup. I decided to investigate what would happen if XBL was also saved into the fastload file.

But first, let’s look at the performance with the current behaviour. Reading XBL generally has three steps, the first is to load and parse the source XML document and convert it into an internal representation. The second step is to attach the binding into the document and create the anonymous content. The third and final step is to compile the property and method scripts associated with the binding. Testing shows that the second step takes only 15 percent of the total time, so I’m going to focus on the first and last steps here. (Here I’m only considering the time spent executing within the area of code used to implement XBL.)

This chart shows the time to read a few selected bindings used by the Firefox UI. The first three are some of the pieces that make up the tabbrowser, the fourth is the tree element, the fifth is the dropdown autocomplete popup for the URL address field, and the last is the URL address field itself. This chart only shows a selection of the more complex bindings; in reality about 60 bindings or so are read at startup to create a window.

The chart breaks down the time to load and parse the binding (the blue bar) and the time to compile the properties and method scripts associated with the bindings (the green bar).

The first binding ‘tabbrowser-tabs’ takes a lot longer to parse than the following two tabbrowser related bindings. This should be expected since all three bindings are stored in the same XML file. As the document is only loaded and the XML parsed once per file, we expect that most of the parsing time will be for whatever binding is asked for first. The parse time for ‘tabbrowser’ and ‘tabbrowser-tabbox’ is mostly just overhead from having to locate the cached bindings previously read. (Remember that in-memory caching of XBL is performed currently.)

The compile time for the bindings, especially ‘tabbrowser’ correlates to the amount of script used by that binding. As evidenced, the ‘tabbrowser’ binding has a lot of methods, so significant time is spent on this.

The tree binding shows that a more complex binding that requires both parsing and compiling does indeed require notable time for both parsing and for script compiling.

As with the tabbrowser, the two urlbar bindings are contained within the same file, so the parsing time of the first takes the brunt of the total time. But notice that the ‘urlbar’ also requires significant time to parse as well. Again, there is an explanation. This last binding inherits from the autocomplete binding, so the time here also includes the time to load and parse the base autocomplete binding as well.

As evidenced, script compilation is a significant part of reading a binding. It is this part that we hope to reduce by fastloading.

I implemented a simple XBL fastloading mechanism to see what would happen. The hope is that we can see faster loading if the parsing and compiling steps are replaced by a single mechanism to read data from the fastload file that is already in a format that is close to the in-memory representation used. We can’t eliminate the time entirely of course, as we still need to read the compiled form, but if the original testing is correct, we should be able to eliminate the time needed to compile the scripts at least. The following chart shows the results.

This chart includes a bar showing the time taken when fastloading the same set of bindings (the orange bar) with the original data for comparison.

We can clearly see that the compilation time is entirely gone. The ‘tabbrowser’ binding shows this most obviously as it eliminates over 17 milliseconds off of the original time. But all of the other bindings have also saved this compilation time as well.

In all, it appears that the parse time is reduced by around 20 to 25 percent. In the two cases where parsing is not done, ‘tabbrowser’ and ‘tabbrowser-tabbox’, there is no difference in parse time. Note that in the implementation I did, all of the loading for all bindings in a file happens when the first binding for that file is loaded, so the parse time for all three actually occurs during the first tabbrowser-tabs binding. The small amount that exists is from the overhead of retrieving a binding from a file in the cache that is already been read. That might be worth investigating as well, since this overhead occurs over 500 times just when starting up Firefox.

This last chart shows the total time taken up by XBL parsing and compilation to load all of the bindings using two tests. The first is the time taken during startup. The second is a test which starts the browser, opens the bookmarks window, the sidebar, a couple of panes in the preferences window, a new blank window and then closes them again. As not all elements and bindings are used in the basic Firefox window, this latter test ensures we read a good selection of the additional bindings.

This chart shows that overall, using XBL fastloading removes the time needed for compilation, but has only a marginal effect on the total parsing time.

Note that this testing is only based on a few basic observations, but other tests I’ve done show that similar results occur at least on Windows and Mac, both with optimized and debug builds. Testing suggests about a 3-5% improvement in startup time once the fastload data is cached.

March 2, 2011

Fun with Toolbars

Filed under: Mozilla — enndeakin @ 3:58 pm

I started to work on a prototype for being able to dock panels onto a window, which might be used for the console panel. This would allow one to drag a panel around and snap it into a window so that it was no longer a separate piece of UI.

While looking for a good means to test what I’d implemented, I realized that the simplest was to allow the toolbar to be pulled out of the window.

Or, when dragged near the bottom of the window, the toolbar snaps onto the bottom:

February 5, 2011

Status Update for February 5

Filed under: Mozilla, Status Updates — enndeakin @ 4:36 pm

Things I did this week:

  • Worked on more arrow panel and popup positioning bugs: 524545, 628238, and 629002.
  • A couple of issues with the printer dialog not receiving focus properly: 628157 and 626403.
  • Fixed a problem where pressing the mouse button down to select text but releasing the mouse button on a different frame didn’t cancel selecting mode.
  • Created a patch for an issue where some commands were not working from the context menu for a page loaded in the sidebar.
  • Fixed a problem where key events were being redirected when the focus changes between a content document and a chrome document during the keydown event. An earlier bug had fixed the opposite case.
  • Spent a lot of time on the leak from the resizer patch. It turns out it might not be that patch after all but a global storage related change.
Older Posts »

Create a free website or blog at WordPress.com.