How can a Mac app be so retina unfriendly - cocoa

To my knowledge, the windows, labels, ... etc. are automatically retina-fied when they run on the new MacBooks with Retina Displays. That's the case with most of the apps I have (third party apps I didn't develop). However...
There is this specific app (Yummy ftp), that just looks miserable on the retina. Every single "thing" within the window is non-retina-fied. Even the window's toolbar.
In a counter example, many other apps just got automatically retina-fied (except raster images, CoreGraphics/CoreAnimation stuff, ...etc).
Showcase:
I did not scale these images. I am just screen capturing, cropping, and uploading.
As a cocoa developer, I would like to know the cause of such misbehavior, and how to avoid it.

https://developer.apple.com/library/mac/#documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Introduction/Introduction.html, make sure the guide have be read. "An App’s High-Resolution Capability Is Available in the Info Window
Users can find out whether an app is running in low resolution by opening its Info window and looking at the “Open in Low Resolution” checkbox, as shown in Figure 1-7. Apps that aren’t Cocoa apps have this checkbox selected and unavailable (dimmed). Most Cocoa apps have this checkbox available, but not selected. A user can choose to run a Cocoa app in magnified mode if the app has usability issues related to high resolution.
Figure 1-7 The resolution option in the app’s Info window![enter image description here]
Some Cocoa apps that are not fully optimized for high resolution might have the checkbox selected and available by default. These apps will run in magnified mode unless the user overrides the default setting. Users might want to override the default if the issues related to high resolution are tolerable.
If the “Open in Low Resolution” checkbox is selected by default for your app—whether the checkbox is available (dimmed) or not—you can change the default by:
Fixing all bugs related to high resolution
Setting the NSHighResolutionCapable attribute to YES, in the Info.plist for the app, as shown in Figure 1-8.
Figure 1-8 The key that indicates an app is ready for high resolution![enter image description here]
When users update to the revised version of your app, they will be able to enjoy the high-resolution version.
If your app is optimized for high resolution, you can request that the “Open in Low Resolution” checkbox is not displayed by adding the NSHighResolutionMagnifyAllowed key to the Info.plist for your app. Then, set the key’s value to NO (Boolean value). A value of YES (the default) means that checkbox should be shown as usual."

I found an open-source application that had the exact same problems as Yummy FTP:
Audacity
After exploring the project, I realized that the application was developed in C++ for cross-platform capability, that's why it didn't support the MacBook with retina display automatically. Figuring out if it is possible or not to support the retina display is outside the scope of this question.

Related

"Auto Layout before OS X 10.7"

I have an app in the app store, FractalWorks, which is based on a very old code-base. It's a big app, with quite a few screens. It was created in Objective-C before auto-synthesized properties were a thing, to give you an idea of how long ago it was created.
I wrote the app when I had a full-time gig as an independent software developer. I've since taken a day job, and support my apps in my spare time.
It still sells fairly well, and I recently used to add a section to the Wikipedia article on the Mandelbrot set on 3D images: https://en.wikipedia.org/wiki/Mandelbrot_set#3D_images_of_Mandelbrot_and_Julia_sets
I'm fluent in Auto-Layout now, but haven't taken the time to update the app's XIB files from "struts and springs" style to Auto-Layout - nor do I want to invest the time to do so if I can possibly help it.
I want to add a minor enhancement to the app that involves adding some UI elements and making one of the windows slightly taller. The minute I try to use Interface Builder to edit my XIB, it apparently silently changes it to Auto-Layout, and then complains about "Auto Layout before OS X 10.7". (It was released to the app store for OS X version 10.4, if memory serves, and I've moved the OS version up to the lowest version I could get away with in order to support legacy customers. It currently supports ≥10.6. The original, pre app-store version used even older OS versions.)
Googling this error suggests I use the file inspector on my XIB file to un-check a "Use AutoLayout" checkbox, but I don't see any such checkbox.
What am I missing?
If I use Xcode's code review button to compare the XIB file before and after editing it, various "tool version" values are changed, as well as it gaining a setting useAutolayout="YES". Editing that to read useAutolayout="NO" does not solve the problem.
All the credit goes to matt and his comment.
1. In the Navigator (left panel) go to issue navigator and click on the error.
2. In the Inspectors panel (right panel) the Size inspector will be automatically selected. Switch Layout from Automatic to Translates Mask Into Constraints.
Update: It's called Autoresizing Mask now.
3. Repeat for every occurrence of this error.
You may end up with an error not in the Illegal Configuration group like the following which opens the All Messages view in the middle and doesn't open the Size inspector.
This is a compile time error, just build/run your app again.
And also from the previously mentioned comment:
Be careful not to make any constraints, as that will cause an incoherent situation.
If you have multiple auto layout errors, which in all likelihood you will have, select all the controls in a window and perform the operation once rather than for each individual control. Repeat for each window.

Scaling the non-client area (title bar, menu bar) for per-monitor high-DPI support

Windows 8.1 introduced the ability to have different DPI settings for different monitors. This feature is known as "per-monitor high-DPI support." It persists and has been further refined in Windows 10.
If an application does not opt in (i.e., is either DPI-unaware or high-DPI aware), it will be automatically scaled up by DWM to the proper DPI. Most applications fall into one of these two categories, including most of the utilities bundled with Windows (e.g., Notepad). On my test system, the high-DPI monitor is set to 150% scale (144 DPI), while the normal monitor is set to the system DPI (100% scale, 96 DPI). Therefore, when you open one of these applications on the high-DPI screen (or drag it over there), virtualization kicks in, magnifying everything, but also making it incredibly blurry.
On the other hand, if an application explicitly indicates that it supports per-monitor high-DPI, then no virtualization is performed and the developer is responsible for scaling. Microsoft has a fairly comprehensive explanation here*, but for the benefit of a self-contained question, I'll summarize. First, you indicate support by setting <dpiAware>True/PM</dpiAware> in the manifest. This opts you into receiving WM_DPICHANGED messages, which tells you both the new DPI setting as well as a suggested new size and position for your window. It also allows you to call the GetDpiForMonitor function and obtain the actual DPI, without being lied to for compatibility reasons. Kenny Kerr has also written up a comprehensive tutorial.
I've gotten all of this going successfully in a little C++ test app. It's a lot of boilerplate and mostly project settings, so I don't see much point in posting a full example here. If you want to test it out, either follow Kenny's instructions, this tutorial on MSDN, or download the official SDK sample. Now, the text in the client area looks good (because of my handling of WM_DPICHANGED), but because virtualization is no longer performed, there is no scaling of the non-client area. The result is that the title/caption bar and the menu bar are the wrong size—they do not get larger on the high-DPI screen:
So the question is, how do I get the non-client area of the window to scale to the new DPI?
It doesn't matter whether you create your own window class or use a dialog—they have identical behavior in this respect.
It has been suggested that there is no answer—that your only choice is to custom draw the entire window, including the non-client area. While this is certainly possible, and indeed what UWP apps (those previously known as Metro) do, like the Windows 10 Calculator, it is not a workable option for desktop applications that use many non-client widgets and hope to look native.
Aside from that, it is demonstrably false. Custom-drawn title bars cannot be the only way of getting the correct behavior, since the Windows shell team has done it. The humble Run dialog behaves exactly as expected, properly resizing both the client and non-client areas as you drag it between monitors with different DPIs:
Investigation with Spy++ confirms this is just a bog-standard Win32 dialog—nothing fancy. All of the controls are standard Win32 SDK controls. It is not a UWP app, nor have they custom-drawn the title bar—it still has the WS_CAPTION style. It is launched by the explorer.exe process, which is marked as per-monitor high-DPI aware (verified with Process Explorer and GetProcessDpiAwareness). This blog post confirms that both the Run dialog and the Command Prompt have been rewritten in Windows 10 to scale correctly (see "Command shells et al."). What is the Run dialog doing to resize its title bar?
The Common Item Dialog API, responsible for new-style Open and Save dialogs, also scales correctly when launched from a process that is per-monitor high-DPI aware, as you can see when clicking the "Browse" button from the Run dialog. Same thing for the Task Dialog API, creating the odd situation where an app launches a dialog box with a different-size title bar. (The legacy MessageBox API has not been updated, however, and exhibits the same behavior as my test app.)
If the shell team is doing it, it has to be possible. I just cannot imagine that the team responsible for designing/implementing per-monitor DPI support neglected to provide a reasonable way for developers to produce compatible applications. Features like this require developer support, or they are broken out-of-the-box. Even WPF applications are broken—Microsoft's Per-Monitor Aware WPF Sample project fails to scale the non-client area, resulting in a title bar that is the wrong size. I'm not much for conspiracy theories, but this smells of a marketing move to discourage desktop app development. If so, and there is no official way, I'll accept answers that rely on undocumented behavior.
Speaking of undocumented behavior, logging window messages when the Run dialog is dragged between monitors with different DPI settings shows that it receives an undocumented message, 0x02E1. This is somewhat interesting because this message ID is exactly one greater than the documented WM_DPICHANGED message (0x02E0). My test app never gets this message, though, regardless of its DPI-awareness settings. (Curiously, close inspection does reveal that Windows slightly increases the size of the minimize/maximize/close glyphs on the title bar as the window moves onto the high-DPI monitor. They're still not as big as they are when they are virtualized, but they're slightly bigger than the glyphs that it uses for unscaled system-DPI applications.)
So far, my best idea has been to handle the WM_NCCALCSIZE message to adjust the size of the non-client area. By using the SWP_FRAMECHANGED flag with the SetWindowPos function, I can force the window to resize and redraw its non-client area in response to WM_DPICHANGED. This works fine to reduce the height of the title bar, or even remove it altogether, but it will never make it any taller. The caption seems to peak out at the height determined by the system DPI. Even if it worked, this wouldn't be the ideal solution, because it wouldn't help with the system-drawn menu bar or scroll bars…but at least it would be a start. Other ideas?
* I know that this article says "Note that the non-client area of a per monitor–DPI aware application is not scaled by Windows, and will appear proportionately smaller on a high DPI display." See above for why that is (1) wrong and (2) unsatisfactory. I'm looking for a workaround other than custom-drawing the non-client area.
In any up-to-date Windows Insider builds (build >= 14342, SDK version# >= 14332) there is an EnableNonClientDpiScaling API (which takes an HWND as its argument) that will enable non-client DPI scaling for top-level HWNDs. This functionality requires that the top-level window be running in per-monitor DPI-awareness mode. This API should be called from the WM_NCCREATE handler for the window. When this API is called on a top-level window, its caption bar, top-level scrollbars, system menu and menubar will DPI scale when the application’s DPI changes (this can happen when the app is moved to a display with a different display scaling value or when the DPI changes for other reasons such as the user making a settings change or when an RDP connection changes the scale factor).
This API does not support scaling non-client area for child windows, such as scroll bars in a child window.
To my knowledge there is no way to have non-client area DPI scale automatically without this API.
Note that this API has not yet been finalized, and it may change prior to being released in the Windows 10 Anniversary update. Keep your eye on MSDN for official documentation when it becomes final.
With Per Monitor V2 DPI awareness in Windows 10 Creators Update (build 15063) you can resolve this easily without the EnableNonClientDpiScaling.
To enable Per Monitor V2 DPI awareness, while still supporting old Per Monitor DPI awareness on older Windows 10 builds and Windows 8.1 and DPI awareness on yet older versions of Windows, make your application manifest like this:
<assembly ...>
<!-- ... --->
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
References:
High DPI Improvements for Desktop App Developers in the Windows 10 Creators Update – video (archived)
Application Manifests – reference
High DPI Desktop Application Development on Windows – documentation
Note that in WinForms targeting .NET 4.7 and later, you can achieve the same by adding
<add key="DpiAwareness" value="PerMonitorV2" />
to <System.Windows.Forms.ApplicationConfigurationSection> tag in app.config. I assume that in the end, this change modifies the manifest in the target binary as described above.

How to test what a webpage/web app will look like with Firefox on a specific screen resolution

I have the task of testing a web application where it is given that this app should fit a screen with the resolution of 1280*1024.
My work monitor is, however, a 20 inch screen with resolution 1680*1050.
Will resizing the Firefox window to 1280*1024 meet the test criteria or should I always change the resolution of my monitor? (Obviously, the second option is not preferred).
And also: Is there a Firefox plugin which will help me to set the window size appropriately?
Sometimes asking the question out loud helps to realise what you really want :)
There is Firefox addon called More Display Resolutions which helps to show the page in given resolution, even in 1280*1024
After you install it, just go to Tools -> Web Developer- > Responsive Design View and here you can turn on the preffered resolution:
Ok, the above died. What now?
Since time of writing this answer I changed jobs and do not have to test specific resolutions. But I did quick google search and this site seems to be working: http://quirktools.com/screenfly/
Responsive Design Mode is a stock part of Firefox which is available from the Menu Bar: Tools -> Web Developer -> Responsive Design View in all Firefox versions (keyboard shortcut: Ctrl + Shift + M, (or Cmd + Opt + M on OS X)). No extension is needed to access this mode.
Within Responsive Design Mode, you can set the exact display area used for the webpage. There are several preset dimensions. Alternately, custom display dimensions can be used by either directly typing the dimensions in, or dragging the display to the size desired. What is being set is the pixel dimensions used for the area containing the display of the webpage.
These dimensions are not the same as setting the pixel dimensions used for the entire screen, which would include the Firefox user interface. If you set it to the dimensions of a specific physical display size it is the same as would be displayed using Full Screen mode (on desktop versions, keyboard shortcut F11). If you want to see what your page will look like including the Firefox user interface, you will need to determine how many pixels the user interface consumes at the screen resolution you are interested in and on the platform you are intending to use (e.g. desktop, Android, iOS). You will then need to use a custom display size. Note that the amount of room used for the Firefox user interface will depend on many factors which include—in addition to the OS and resolution of the physical display—any theme the user has installed, which toolbars the user has chosen to display, and, potentially, which add-ons the user has installed.
This is what Responsive Design Mode looks like:

Where to put copyright notices in a minimal Mac app's UI?

I am doing a minimal port of a simple iPhone/iPad app (think 2D casual game with a single view) to the Mac (almost nothing has changed in the UI, except swapping touchable Cocoa Touch UI elements for mouse-clickable Cocoa UI elements). In the iPhone app, a little "i" button brings up a text view containing basic instructions, followed by all the required (possibly lengthy) BSD/MIT/Apache/Artistic/et.al. copyright notices and their associated disclaimers for any random borrowed code.
The ported Mac app is intended to be distributed from the Mac App store, so additional README files outside the app bundle/sandbox can't be used. I note that many Mac App store apps do not put this text in the About... box, or use a little "i" button like iPhone apps.
So where do I put the equivalent README text in a Mac App Store app?
I would like this text to be included with the Mac app so that it's viewable from within the app even when the Mac is completely off-line.
ADDED:
I see recommendations for putting all this text in the About... dialog, but, if so, my guess is that many apps are skimping on all the required text that seems to go with many of these licenses (I've seen a few with a page or two of required disclaimers. Which Mac app has all that in the About... dialog?)
Just put a Credits.html or Credits.rtf file in your bundle, it'll automatically be displayed in the dialog that's shown after clicking the "About MyApp" item in the main menu.
Usually, a Mac app includes an «About» window, with the application's icon, name, version number and author.
If you have credits to display, you may display them on that window, if it's only a few lines.
If you have a long text, you should add a «credits» button on the «About» window, that eventually opens a specific credits window, with the text you want.

What is the standard screen resolution we should design for in a Mac App Store application?

On the iPhone, we design applications around a standard screen size of 320x480. Is there a standard screen size we should use for developing Mac applications, specifically ones targeted to the Mac App Store?
You don't. Desktop computers don't have a fixed size like phones do. Users could have a screen (or two or six) with a resolution anywhere from 800x600 to 3200x2400 or more.
Instead, design your application to be dynamically resizable. Allow the user to resize windows by dragging their corners to make them as large as they want. Ensure that the layout of elements is fluid, and that they move/resize accordingly as their parent window is resized.
Whatever you do, do not try and lock your users into a particular resolution or window size. They will resent it, and your app will not be very successful. You need to abandon the iPhone model when developing Macintosh applications. There are some similarities, but also lots of important differences.
Examine the other applications on your computer, and see how they behave. Good examples are the applications Apple bundles with new Macs, like iTunes, iPhoto, TextEdit, Pages, and Keynote, among others. Certain third-party companies also design award-winning software applications, like Panic's Coda, Fetch, and even Microsoft Office. Hard to go wrong by following their example.
For all modern macs, at least 1024x768 will be usable screen real estate (the actual screen will be larger, but you need to account for menu bars, 16:9, etc.). Still, this is generally not a good question to ask - you should probably have dialogs that look good at 800x600 and scale larger at the very least - most people like to be able to arrange their windows to their preferences, and if you have a large minimum size that will be very annoying.

Resources