I’ve seen some reports and received some emails on email groups that I’m a part of around Windows 8 and Google Chrome browser and how touch is not working.  In fact I was initially confused about this myself because it was working fine for me on my machine (Lenovo x230t) but other people were insistent that it wasn’t working.  Then I asked what machine they were on.

Almost exclusively everyone was on a “high DPI” machine (or had high DPI settings in their display).  If you have a Surface Pro, for example, you are using a high DPI machine.  I installed Chrome on my Surface Pro and indeed saw the problem there.  After some digging it appears to be that Google Chrome is not yet a high DPI-aware desktop application (at least of this writing which was using version 30.0.1599.66 m – phew that was a mouthful of a version number).

Look at this screenshot.  This is from my Surface Pro with no changes.  I’m tapping on the 2nd image in the news highlights (indicated by the touch square indicator) but notice where the target is actually clicking – on the date “October 4” where the context menu is located:

Chrome missed touch target

I asked around the office and received one workaround, which I received, but also found a better one.  Here are both of them for you to consider.

Workaround 1: run in compatibility mode

This involves you getting to the properties of the chrome.exe program and viewing the compatibility tab.  In there you can check the option to disable DPI scaling:

Chrome compatibility setting

I didn’t like this option because immediately after restarting Chrome the display was crisp but “tiny” to see for my aging eyes.  You can see here is the msn.com site before/after this compatibility setting:

Chrome msn.com before

msn.com on Google Chrome with no compat setting

Chrome msn.com compat set

msn.com on Google Chrome with the compat setting enabled

After this setting the hit-targets are fine and work but the content is small (although admittedly more of it is viewable, but that is too small for me).  To mitigate this you can use Chrome’s zoom feature to zoom to 150% to match most closely the high DPI scaling that automatically happens.

Chrome zoom settings

But there has to be a better way…and is (in my opinion).

Workaround 2: set the Chrome flag for HighDPI Support

I learned that Chrome has “flags” that you can set to experiment with certain settings or override other default/automatic settings.  From the address bar, type “chrome://flags” and you’ll see a page of options.  Scroll near the end and you’ll see a “HighDPI Support Windows” setting which is set to Automatic. 

Chrome HighDPI Flag setting

Force this to Enable and re-launch Chrome.  Boom you are working again.  Simpler fix and gets you scaling on your device as well.  Now some of Chrome’s chrome (menus, etc.) aren’t as crisp still but the main content area doesn’t confuse hit-targeting of your touch interaction because of the scale.

The good part is that it appears that the Chrome team is aware of this and a Chrome bug is logged (Chromium Bug 271222: When using the global Windows UI scaling feature, touchscreen touches are off by the set scale).

I don’t use Chrome on a regular basis (nothing against it, just don’t need it) but do get sad when friends have problems so I like to try to help out.  Hopefully if you are in this case with your touchscreen and Google Chrome this will get you fixed up.

Hope this helps!

A few weeks ago I had the great pleasure of being in front of you, our developer customers (and friends) at the Microsoft BUILD conference. (I never know how to write “build” in a sentence and refuse to use the “//” in front of it.) These are things that I LOVE doing and wish I could do it more. I had the privilege of introducing an overview of what was new in the XAML UI framework for Windows 8.1. All the sessions are recorded so please go view mine and review it how you think so they might invite me back!

In my session I gave some preview of some of the great new XAML tooling that is introduced for developer productivity in Visual Studio 2013 which, as of this writing, is currently in preview form and available for download. My colleague Unni followed my session with one specifically about XAML tooling enhancements with a whirlwind tour of all the new features. Please go check out his session: What’s New in Blend and Visual Studio for XAML Developers for the complete details.

One of the things I showed was the introduction of Visual Studio (VS) code snippets for the XAML editor. This was one of the customer requests for a while for the XAML editor and is now available in the VS 2013 preview! In my presentation I showed a common task that I do which is to have many elements and wrap them in a StackPanel. I’ve gotten lazy and wanted a quick ‘refactor’ way to do this and now I can! A few have emailed me asking where the snippet I used was as nothing was working in the preview for them. As of this writing, the functionality was in the preview, however no default XAML code snippets are provided. I’ve responded to a few on an MSDN forum thread offering to share my snippets and someone suggested I post more details, so here it is!

Anatomy of a Code Snippet

Code Snippets in VS are basically XML files that sit in a special location (one of two locations, global or user). These code snippets can apply to many things including languages (C#, VB, etc.) as well as ‘markup’ languages (CSS and now XAML). You can read more in-depth data about VS Code Snippets here. The basics that I think you want to know are the two main types of snippets: Expansion and SurroundWith.

An Expansion snippet is one that you invoke and it gives you placeholders for stuff to fill out. My most widely used one is ‘foreach’ in C#. You start typing foreach, then hit tab-tab and you are presented with a template, more or less, to complete. A SurroundWith snippet is one that surrounds (duh!) the selected content in the editor surface with your template. An example of this is the #region snippet which puts the begin/end region tags around selected code. It is important to note that these can be used exclusively or together. That is to say I can have a SurroundWith snippet that is also an Expansion. In fact, the #region one is a good example: it surrounds the selected code and also gives you a field to complete for the region name. The Code Snippet structure is the same for most languages with the difference being that in the Code node of the snippet definition it defines which language it applies to for the editors.

NOTE: Creating Code Snippets is a very manual process. At the time of this writing there was no really great tool to “extract” a chunk of code and turn it into a code snippet. There are a few attempts out there, but most have been abandoned and not all working.

Once you have these XML files (.snippet files for VS), you place them in well-known locations or can use the Code Snippets manager in VS (more on that later).

XAML Code Snippets

As noted above the XAML code snippets are the same structure as the C# snippets with the difference being the Language attribute on the Code node in the definition. In my demo I used a StackPanel SurroundWith snippet with the following definition:

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <SnippetTypes>
      <SnippetType>SurroundsWith</SnippetType>
    </SnippetTypes>
    <Title>Vertical StackPanel</Title>
    <Author>Tim Heuer</Author>
    <Description>XAML snippet for surrounding content in a vertical StackPanel</Description>
    <HelpUrl>
    </HelpUrl>
    <Shortcut>vsp</Shortcut>
  </Header>
  <Snippet>
    <Code Language="XAML"><![CDATA[<StackPanel>$selected$$end$</StackPanel>]]></Code>
  </Snippet>
</CodeSnippet>

Notice the <Code> element and how it has the Language=”XAML”? That is the only difference between this and a C# one. There are keywords for certain things like selected (which is a marker for selected content) and end (which is where you want the cursor to be at the completion of the snippet) that you can use and are in the documentation. Here is another example of an Expansion XAML snippet for an AppBarButton:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>AppBarButton</Title>
            <Shortcut>abb</Shortcut>
            <Description>Code snippet for XAML AppBarButton</Description>
            <Author>Tim Heuer</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>icon</ID>
                    <ToolTip>The Icon value to use for the visual</ToolTip>
                    <Default>Emoji</Default>
                </Literal>
                <Literal>
                    <ID>label</ID>
                    <ToolTip>The text label for the button</ToolTip>
                    <Default>My Label</Default>
                </Literal>
                <Literal>
                    <ID>uniqueid</ID>
                    <ToolTip>The unique ID for the button</ToolTip>
                    <Default>MyAppBarButton</Default>
                </Literal>
            </Declarations>
            <Code Language="XAML"><![CDATA[<AppBarButton x:Uid="$uniqueid$" x:Name="$uniqueid$" Label="$label$" Icon="$icon$" />$end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

As you can see they are pretty simple to use!

Adding Code Snippets to VS

There are two ways to distribute snippets: as raw .snippet files or with an installer. You can send someone a .snippet file and they can use the Code Snippets Manager tool to import it into their environment. This is a per-user method. From VS you would use the Tools menu and choose the Code Snippets manager:

<pic>

From here you would navigate to the XAML folder, then choose Import and select your .snippet files. These would then import them into your local profile (Documents\Visual Studio 2013\Code Snippets) and be ready for immediate use. Another way is through an installer. Now up until VS 2013 there was the VSI installer (as documented here on MSDN) which has since been eclipsed by the VSIX extensibility method. Right now there doesn’t appear to be much documentation on this method, but you *can* distribute code snippets via the VSIX installer. VSIX is basically a ZIP file format with a manifest and content. For this purpose the manifest describes the targets and the package definition for the VSPackage we are installing, which is in this case a folder of snippets. This is a little tricky method to get VSIX to use as an installer for snippets, but works. I won’t detail out the entire process here, but leave you with a few screenshots and you can download the file and look at the contents to see how it works…again it is a regular ZIP file so just rename and explore.

Contents of VSIX:

Contents of VSIX package

Installer dialog:

VSIX installer dialog

Once installed your VSIX-deployed snippets show up in the Extension Manager:

Extension manager listing

And there you have it! A simple way to distribute your code snippets. This VSIX can be put on VS gallery as well so that you can update it there and anyone who installed it can get updates from within VS itself!

To actually use the code snippets, from within the XAML editor use the shortcuts CTRL+K,S (for surround snippets):

Surround code snippet

or CTRL+K,X (for expansion snippets):

Expansion snippet

Expansion snippet completed

Summary

Code snippets can be a powerful productivity tool for VS. You probably use them daily (like foreach) and maybe didn’t even realize it! Now that this concept is extended to XAML there are some great opportunities to increase your markup productivity by encapsulating some things that you do often into a XAML code snippet. Right now the VS gallery doesn’t support uploading the method for VSIX that I have described so you can download my VSIX for some code snippets examples here for now.

Hope this helps!

Those of us who work for corporations/companies/whatever (read: not self-employed) usually get an allotment of vacation (or ‘PTO’ – personal time off) each year.  Most companies have policies that put a cap on the amount of PTO you can carry over year after year.  Anything you don’t use, you lose.  You’d be an idiot to lose PTO (which is effectively paid days of work). 

I was an idiot last year.

At the end of the year I got the email from HR indicating that I was going to forfeit a lot of vacation if I didn’t use it.  The problem?  The math didn’t even work out that I could even use it.  It was forfeiture by idiocy for sure.  I left money on the table, but more importantly it led me to a realization that has been obvious to me, of course, for a long time.

I work too much.

I love my job.  I really do.  I enjoy going to work every day, I enjoy the people I work with, and I love the technology that I’m working with daily.  My work is also my hobby/passion.  This presents a problem for my non-work life and a conflict in what people call ‘work/life balance.’

Working from home

For the first 5 years working for Microsoft I was able to work from home.  This provided me the flexibility (an incredible flexibility I might add) of being there for my family when I needed as well as being able to succeed at work.  My commute was downstairs.  I ate lunch with my friends (yes, I realize work folks can be friends as well, but not always the case).  I was able to take/pickup my kids from school.  In the hot summer days I could go outside and jump in the pool.  Okay I rarely did that, but I could.  Reflecting on this time, I never really cared about vacation because I truly did have a decent work/life balance.  Yes, I still worked a lot, but felt I was “there” for my family.  They may disagree, of course.

Working in an office

3 years ago I moved to our corporate offices in Washington.  Aside from the other challenges of relocating a family, my fundamental work structure changed.  I don’t work from home.  I go into an office, mingle with co-workers, drown in meetings and lose track of time to realize that I’m not making it home for dinner at times.  Vacation has a different meaning and is more important…or should be.  Since I spend more time away from those niceties of seeing friends/family very frequently during the day, my perspective has certainly changed.

I spend more awake time in my office than I do in my home during the week.  Think about that.  If you work at a company, you likely do as well.  So why are us workaholics giving up so much time given to us in our vacation?

Philosophy conflicts with career growth

In reflecting on this work/life balance (or imbalance) I have, a co-worker pointed me to a blog post from Jon Gallant on this very topic.  It is a good read and resonated (too well) with me likely because he also works at Microsoft.  I shared this post with some other community-driven guys in the company and started some more thoughts.  One of which (and somewhat pointed out in Jon’s post) is that establishing a real work/life balance is in conflict with career growth, stack ranking systems, etc.  On this point I agree.  However, it all comes down to priorities.  If you want upward career growth you are sacrificing something.  If you want massive family time, you are likely sacrificing career growth.  A small discussion happened about how you can’t even be in the middle and have a job.  I don’t subscribe to that, but understand that every org/division/manager is different and that is something you have to manage against in your role at work.  One thing pointed out in Jon’s post is so true:

“At work you can be replaced in about 5 minutes, but you are effectively irreplaceable at home. Keep that in mind. I think about it every day.”

I shared some thoughts with Jon via email, thanking him for writing what was in my head for so long and we shared some more thoughts.  In the end, his final comments to me were something I don’t think anyone could argue with (note the ‘number’ refers to the stack ranking system), emphasis mine:

The [rank] [your company] gives you doesn’t mean anything.  No one is EVER going to bring it up in my house – except me. No one cares.  Especially my 2 year old.  I’ll get whatever rank I get this year...it doesn’t bother me because I know that the time I would have put in to always getting the absolute top rank I was at the playground with my kid or teaching him how to ask to be excused from the table.

It made me pause and realize how true that is.  I need to get better at this.  I need to stop saying “just wait one second” to my kids so much.  In fact, Jon got an email from a co-worker that I thought was funny as well…his co-worker *who was on vacation even* said:

“One of my directs was on the beach celebrating his kid’s birthday when he read it.  He put down his phone and went to play with his kid.”

Yep…been there.  Bottom line, there is NEVER a good time to take vacation.  I’ve used that excuse too much.  I need to stop.  My career may suffer.  My thirst for knowing everything around me may suffer.  My family and my own personal sanity will not suffer.  I hope that I can find that right balance as I continue to grow both as a parent/husband and a professional.  I’m not perfect, haven’t found it, but strive to achieve a true work/life balance.

Anyhow, I hope you read his post.  And I hope you are better and balance than I am currently.

In my working with Windows Store apps, I’ve become increasingly fond/aware of the advantages for app localization.  There are a lot of resources out there for you to localize your app using a good-better-best approach as well.  I’ve previously written about localizing a Windows Store app using some of these methods and what the WinRT platform supports to make this easier in most cases.

Now that you’ve localized your app, you may be faced with the question of how you might want to respond to language choice changes by the user.  Remember that the Windows Store app model is that it honors the user’s language choice preferences matching that with the available languages the app indicates it supports.  This may not always map to the user’s installed OS language.  For instance I can have an English OS install but prefer German in my apps and set my language preference to: de-DE, en-US.  If a Windows Store app was localized in German, then I would see that version instead of English because my preferences say so, regardless of my OS install.

Language switching problem

Now, I’m not as proficient in German as I’d like to be, so there may be times where I need to flip back to English to understand certain areas of an app.  I can do this easily by going to the languages panel and switching my order of preference:

But when I go back to my app, it is still in German…until I terminate/restart the app.  Let’s say I started the app and it honors my language preference:

Now I go and change back to English and click the button to take me to page 2.  It is still in German even though my language preference list is now: en-US; de-DE.

The XAML framework doesn’t automatically re-evaluate the resource cache in response to these changes.  This is something the developer has to manage and luckily there are some easy steps you can do to make this experience better for your users.

We should point out that this is likely a rare case that a user of your app is constantly switching languages and switching back to your app, but having your app support this is a delighter for your users when it does happen.

Solution: listening to qualifier updates

There are APIs to the rescue here!  When you switch your language preferences, the system actually is aware of it, however the context that your app already had at launched has been cached…and thus it will still be delivering the original context-aware resources.  Good for us is that the APIs can let us know when this happens and we can respond.

Since most apps have only a single Window object and since this change is likely rare, we should manage this call and not put it on every Page load, for example, but rather higher up in the App because it will likely be rare that it happens.  In our activation code path we can listen for the resource context to change

   1: protected override void OnLaunched(LaunchActivatedEventArgs args)
   2: {
   3:     ...
   4:     ResourceManager.Current.DefaultContext.QualifierValues.MapChanged += QualifierValues_MapChanged;
   5:     ...
   6: }

In this snippet we are using the default ResourceContext and listening for when its qualifier map changes.  The qualifier map is the set of context for resources like language, but also scale, phonetics (for Japanese), high contrast, etc.  Once that map changes we can force a refresh of the cache essentially:

   1: void QualifierValues_MapChanged(IObservableMap<string, string> sender, IMapChangedEventArgs<string> @event)
   2: {
   3:     ResourceManager.Current.DefaultContext.Reset();
   4: }

This simple flow basically says “hey, when a qualifier has changed, reset the context map so that I get the new data” and our app in subsequent calls to the resources will get the updated resources.

Here’s a video demonstrating the completed before/after approach.

There is a big caveat to this approach.  The change doesn’t automatically affect your current view.  So your page has rendered and is in German.  If I go and change it to English, then go back to my page…it isn’t automatically in English.  Subsequent view loads (and even going back to this page) will get the new resources, but already-rendered ones do not.  The developer can, of course, implement way more logic to refresh the view, traverse the tree, etc. to manage this, but that experience is up to the app developer to determine what is most appropriate for the app itself.

This is a little subtle but helpful tip in enabling your localized apps to be flexible to these types of changes by users when that happens.

Hope this helps!

As someone who uses a few iOS devices around the house, I’ve become fond of visiting sites and seeing a little banner that lets me know that a native app is available for the web app I’m using.  This concept was introduced in iOS 6 and called “Smart App Banners” in the developer documentation.  You may have seen them as well

Smart App Banner example

I wanted to provide the same affordance for Windows Store apps and recalled there are already two ways to integrate the web app browsing experience with the native app in the Windows Store:

In iOS, this is implemented a bit natively in mobile Safari, not through any additional JavaScript files/functions.  As with any random idea I have, I always set out to search if it has been done before (often it already has).  I couldn’t find something like this specifically for Windows Store apps, however I did find an implementation for pre-iOS6 browsers as well as Android.  It was from Arnold Daniels and hosted on GitHub, so what’s a guy to do?  Fork it!

And that’s what I did: https://github.com/timheuer/jquery.smartbanner

With a few more conditional checks, if you put this in your web app/site now you’ll get it automatically linked to your Windows Store app if you have the correct meta tags.  For the implementation for Windows Store apps I’ve made some assumptions about the meta tags used.  The following would get you a good experience:

   1: <html>
   2:   <head>
   3:     <title>Hulu Plus</title>
   4:     <meta name="author" content="Hulu LLC"/>
   5:     <meta name="msApplication-ID" content="App" />
   6:     <meta name="msApplication-PackageFamilyName" content="HuluLLC.HuluPlus_fphbd361v8tya" />
   7:     <link rel="stylesheet" href="jquery.smartbanner.css" type="text/css" media="screen"/>
   8:     <meta name="msapplication-TileImage" content="http://wscont1.apps.microsoft.com/winstore/1x/c8ac8bab-d412-4981-8f31-2d163815afe4/Icon.6809.png" />
   9:   </head>
  10:   <body>
  11:         <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
   1:  
   2:         <script src="jquery.smartbanner.js">
   1: </script>
   2:         <script type="text/javascript">
   3:             $(function () { $.smartbanner() })
   4:         
</script>
  12:   </body>
  13: </html>

If you have the combination of linking your app using the msApplication-ID and msApplication-PackageFamilyName values and the pinned sites high fidelity msApplication-TileImage value to deliver the combined experience.  If you have all these, then the banner “just works” for you.

NOTE: Because the Microsoft documentation mixes msApplication and msapplication (note the casing on the “A”), you should use the capitalization (which is more consistent in the documentation) for ensuring it all works smoothly. 

Now some may use a different pinned site TileImage than that of what they may use for the app tile, however this can also be overridden in the options:

   1: $(function () { $.smartbanner({ icon:'http://some/url/to/tile/image.png' }) })

When done the web app/site would display a dismissable banner (using Hulu as an example here) on a machine running Windows 8:

Hulu smart app banner example

So adding one reference, 2 files and an initialization and you’ll help give your app a bit more promotional flare for those viewing in browsers other than the ‘modern’ IE view.  As you can see the screenshot above is from the desktop version which doesn’t take advantage of the other msApplication-** attribute usage in desktop mode.  The one thing it doesn’t do that the iOS system-level banner does is detect if the app is installed and change “view” to “open” however there isn’t a mechanism to easily detect if the app is installed using JavaScript from a web app.

NOTE: While the ‘View in Store’ button works in IE, Safari and Firefox it does not work in Chrome.  I’m not sure what any timeframe it would be for Chrome to support the store launch protocol.

Anyhow, I thought this might be a useful addition to app developers web apps that have a Windows Store app counterpart (and perhaps already have an iOS and Androi counterpart as well).  I’ve submitted a pull request to the project I forked from, but you can get it from my GitHub repository for jquery.smartbanner.

Hope this helps!