Sergio and the sigil

One less diacritical mark to annoy me

Posted by Sergio on 2008-12-26

Being a Portuguese-speaking person living in the US, one of the things you have to get used to is the keyboard physical layout and key mappings. You know, Latin-originated languages tend to have thôse wéìrd chãraçtërs, which are really just diacritical marks applied to regular characters to differentiate words (sometimes it changes the pronunciation, sometimes i doesn't.)

To accommodate the extra characters, many countries define their own standard for physical keyboard layout. In Brazil the standards body is called ABNT and they came up with the layout that you can see below. It's a mild variation from the one used in the US and works well if you type in Portuguese most of the time.

Even when I was living in Brazil, when I started using computers at home and at work, it was easier to find a keyboard with a US layout than one with the ABNT layout (this situation has changed now.) I chose to stick to a keyboard with the US physical layout and, when in Windows — which was most of the time anyway — apply the US-International key mappings.

What happens when you use the US-International it that some keys become dead keys and when you strike them no characters are echoed. The OS waits for the next key(s) to decide what to print. For example, if I type [ " ][ a ][ b ][ c ] without the US-International mapping, I get (unsurprisingly) "abc. With US-International on I get äbc. I'd have to type [ " ][space][ a ][ b ][ c ] to get the intended text. Other dead keys are [ ' ],[ ` ],[ ^ ],[ ~ ].

Of all these dead keys, the ones that hit me the hardest are [ " ] and [ ' ] because I use them all the time when writing source code.

Where am I going with all this?

As of January 1st 2009 all Portuguese-speaking countries will start complying with an agreement that will cause some orthographic changes in the language. One of the new rules is that the umlaut (those two dots above some letters) is being dropped from the language.

I'm so happy with this decision that I simply could not wait until the US-International key mapping gets updated in some Windows update super Tuesday. I decided to take matters on my own hands and yank that nasty thing off my system.

How to create/edit keyboard layouts (mappings)

Microsoft published a cool little tool called Keyboard Layout Creator that allows you to create or edit the keyboard layouts.

It doesn't get much simpler than that. I installed and run this program. Then I loaded the existing US-International layout and saved it as US-International-No-Umlaut. Mousing over the ["] key would reveal that it indeed is marked as dead and show all the available combinations.

From there I just needed to right-click that key and un-check the option that was setting it as a dead key.

The next step is to compile the new layout into a DLL and create the setup package for it. That is done by the menu option Project > Build DLL and Setup Project.

After running the produced setup program, I could just go into the regional settings of my system and select the new layout (mapping) as my default setting.

If you are another Portuguese-speaking programmer and don't feel like going through the same steps, you can just download the setup files I created.

Now I just need to get rid of that muscle memory that I acquired after all these years.

Presentation Remote

Posted by Sergio on 2008-12-20

In the last few months I have been using my MacBook to give presentation, both at work and not. I've been meaning to buy one of those presenter remotes. I even got to borrow one and tried it once and I must say it worked pretty well.

Then I remembered that the MacBook came with that useless remote that I had forgotten in a junk drawer somewhere. Well, that remote happens to work well with more than just Front Row. I heard it works with Keynote for presentations. I don't use that application and I'm not planning to buy it since Powerpoint 2007 works very well for me on my PC and I'm too cheap to buy Keynote.

I typically save my PowerPoint presentations to PDF and show them on the mac using Preview (a simple PDF viewer). The remote does not work with Preview out of the box but I found this little freeware called iRed Lite that can make the apple remote control just about any application, as long as the application is controllable with AppleScript, which most apps are.

The only problem was that iRed Lite came with support for Preview but it did not work well for the full screen mode, which I needed. Time to get my hands dirty with AppleScript.

The idea here was to bind the commands associated with the left and right arrows of the remote to the keys PageUp and PageDown, respectively.

The iRed Lite utility allows you to edit each command by assigning a keystroke or an AppleScript snippet. Initially I tried the keystroke alternative but I could not figure out how to send a PageDown or PageUp to the application because on the keyboard they are Fn+UP and Fn+DOWN and Fn was not available in the utility. The AppleScript ended up being rather minimal, as seen in the screenshot.

For the Next Page command I entered:

tell application "System Events" to key code 121

For the Previous Page command I entered:

tell application "System Events" to key code 116

You can find all these key codes in the file /System/Library/Frameworks/Carbon.framework/Frameworks/ HIToolbox.framework/Headers/Events.h provided you installed the developer tools from the OS X installation DVD, i.e. you have Xcode installed.

Wow. All this trouble to save $50? I guess I just liked the fact that I found a use for that remote. Now I just need to hack a laser diode inside the remote to use as a pointer too.

Reusing Views in ASP.NET MVC for Ajax Updates

Posted by Sergio on 2008-12-05

The other day I came across this post in Marteen Balliauw's blog where he demonstrates and interesting way to make the same ASP.NET MVC view render correctly from both a regular request and an Ajax request.

In Marteen's post he uses a custom ActionFilterAttribute to detect the Ajax call and replace the standard master page with an unadorned Empty master page.

I liked the idea that you can add that behavior to any action simply by bolting that attribute to it.

What I'm going to illustrate here is a variation of that idea that can be used when you have your own base class to all your controllers, which is something I always do.

SIDE NOTE: I have the habit of creating base classes for all the important things in my ASP.NET applications right after I create the project. I carried this habit from the ASP.NET Webforms-style to the MVC projects. So I typically have ApplicationController, ApplicationView<T>, PartialView<T>, ApplicationMaster, etc. These classes start off empty but code starts finding its way to them rather quickly.

What I'm going to do is override the Controller.View() method to detect the Ajax calls and replace the master page right there.

public abstract class ApplicationController: Controller
{
  protected override ViewResult View(
            string viewName, string masterName, object model)
  {
    if(IsAjaxRequest)
      return base.View(viewName, "Empty", model);

    return base.View(viewName, masterName, model);
  }

  protected virtual bool IsAjaxRequest
  {
    //Both Prototype.js and jQuery send 
    // the X-Requested-With header in Ajax calls
    get
    {
      var request = ControllerContext.HttpContext.Request;
      return (request.Headers["X-Requested-With"] == "XMLHttpRequest");
    }
  }
}

With that in place I don't need to change anything in my action code to start supporting the Ajax calls (as long as the controller inherits from the above base class)

public class SampleController : ApplicationController
{
  public ActionResult Index()
  {
    return View();
  }

  public ActionResult Details(int id)
  {
    var user = new UserInfo {Name = "user" + id, Age = 30};
    return View(user);
  }
}

My Index action calls the Details action using both a regular request and an Ajax call, for the sake of the example.

<%@ Page Title="" Language="C#" 
  MasterPageFile="~/Views/Shared/Site.Master" 
  AutoEventWireup="true" 
  CodeBehind="Index.aspx.cs" 
  Inherits="MvcBeta1.Views.Sample.Index" %>
<asp:Content ID="Content1" 
        ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View Index</h2>
<%= Html.ActionLink("Go to Details", "Details", new { id = 123 })%>
<hr />
<input type="button"  id="loadDetails" value="Load with Ajax" />
<div id="detailsDiv" style="background-color:#aaa;">
[details should load here]
</div>

<script>
  $(function() {
    $('#loadDetails').click(function() {
      $('#detailsDiv').
        load('<%= Url.Action("Details", new {id = 123}) %>');
    });
  });
</script>
</asp:Content>

The Details view is trivial. It's just a table.

<%@ Page Title="" Language="C#" 
  MasterPageFile="~/Views/Shared/Site.Master"
  AutoEventWireup="true" 
  CodeBehind="Details.aspx.cs" 
  Inherits="MvcBeta1.Views.Sample.Details" %>
<asp:Content ID="Content1" 
        ContentPlaceHolderID="MainContent" runat="server">
  <h2>Details for <%= ViewData.Model.Name %></h2>
  <table border="1">
    <tr><th>Col 1</th><th>Col 2</th><th>Col 3</th></tr>
    <% for(int i=1; i<= 5; i++) { %>
      <tr>
        <td>cell (<%= i %>, 1)</td>
        <td>cell (<%= i %>, 2)</td>
        <td>cell (<%= i %>, 3)</td>
      </tr>
    <%} %>
  </table>
</asp:Content>

When at the Index page we can click on the "Go to Details" link and see the full rendering of the Details view.

If we had instead clicked the "Load with Ajax" button we would cause a simpler version of that page to be inserted in the detailsDiv element (note that the tabs and the blue background that surrounds the table did not come in the rendered content.)

Of course, ASPX files are not the indicated place for placing content that can be used in partial updates, ASCX files would be a better choice for that. That said, sometimes it can be really convenient to have this ability.

Please open my .aspx fast

Posted by Sergio on 2008-11-22

Still in the topic of performance, I'll throw a little freebie. Visual Studio seems to take an inordinate amount of time to open .aspx files for the first time. I noticed that the status bar read "Initializing toolbox..." for a long time. I'm mentioning .aspx but it really applies to any other webforms markup like .ascx and .master as well.

Heck, I don't even have the toolbox loaded, docked, or hidden in my IDE. I don't use the toolbox at all for web develoment. I'm more of a source view kind of programmer. So why should I be penalized like that?

I shouldn't. Here's what I did to speed that up:

  • Show the toolbox
  • Right-click and select "Choose Items..."
  • Uncheck every item that the namespace contains "Web" (I also unchecked controls that I can't stand, like the database connections and data sources.)
  • Click OK to save that, close the toolbox again and enjoy your precious stolen time again.

Sluggish Windows in VMWare Fusion - Solved

Posted by Sergio on 2008-11-22

I've had my MacBook for over 2 years. Initially I avoided installing virtualization or even BootCamp to run Windows. I was forcing myself to adapt to OS X, get out of my comfort zone, and learn more about that different environment. The mac was also my Ruby On Rails development machine and I wanted to keep Visual Studio out of it.

After one year, I decided that the hardest phase of the learning process was long gone and I installed VMWare Fusion (version 1.something - don't remember) and Windows XP with Visual Studio. I also bumped up my RAM to 2Gb.

Using Visual Studio inside a VM on a mac was a surprisingly viable alternative. I could have all the mundane applications like web browsers, email clients, IM, Twitter, word processors, etc, be mac applications running in the host and leave a very spartan Windows installation with just the minimum required software.

Enter Fusion v2.0. I honestly don't know at what point things started going downhill. More or less around the same time, maybe 4 or 5 months ago, I applied XP SP3, upgraded Fusion to 2.0, and installed VS2008 SP1. I don't even remember what order I followed anymore. I just know that my Windows VM became almost unusable. I'd click and wait. Visual Studio was so unresponsive that I would prefer to terminal in to my desktop Vista and work like that instead of the VM.

Today I had some time to get back to this problem and do a little googling on it. After a few not so useful hits, I landed on this forum posting that got me back on track.

I still don't know if all my messed up settings were done by yours truly, trying to solve the problem and making it worse, or by the Fusion upgrade. For now I'll assume it was me. Here's what I had to change.

  • Give less memory to the VM. This seems counterintuitive, but I had divided the RAM 50/50 between OS X and the VM. I reduced the VM to around 820MB.
  • Use only one virtual processor. I have a dual core processor but virtualizing only one seems to ensure the host always has at least one entire core to do the housekeeping.
  • Optimize for Mac OS. Mine was optimized for VM. Probably done by myself with the best intentions in the world.
  • No sharing of any applications. I just don't need that. Gone.

Several people on the forums mentioned reinstalling the VMWare Tools. Mine had installed/upgraded fine before so I didn't touch that.

With all these tweaks in place I'm again a happy camper and stopped making plans to buy one of the new MacBook models that support more than 2GB. Performance is back to it's Fusion v1.x days and that's all I was asking for.