Weblog entries 2014

2014-12-15 Shadows and rounded corners

The app I'm currently working on, requires a textfield with shadow and rounded corners. That doesn't work on a UITextField; you'll have to make it transparent, then add it to a plain UIView and style that.

I got curious and tried to add shadows and rounded corners to a number of elements in UIKit. This is the code:

        import UIKit
	class ViewController: UIViewController {
		
		@IBOutlet weak var contentView: UIView!
		@IBOutlet weak var button: UIButton!
		@IBOutlet weak var textfield: UITextField!
		@IBOutlet weak var textView: UITextView!
		@IBOutlet weak var datePicker: UIDatePicker!
		@IBOutlet weak var toolbar: UIToolbar!
		@IBOutlet weak var imageView: UIImageView!
		override func viewDidLoad() {
			super.viewDidLoad()
			self.addShadowAndCornerRadius(self.contentView)
			self.addShadowAndCornerRadius(self.textfield)
			self.addShadowAndCornerRadius(self.button)
			self.addShadowAndCornerRadius(self.textView)
			self.addShadowAndCornerRadius(self.datePicker)
			self.addShadowAndCornerRadius(self.toolbar)
			self.addShadowAndCornerRadius(self.imageView)
			
		}
		
		func addShadowAndCornerRadius(view: UIView) {
			let radius:CGFloat = 20.0
			view.layer.cornerRadius = radius
			view.layer.shadowColor = UIColor.darkGrayColor().CGColor
			view.layer.shadowPath = UIBezierPath(roundedRect: view.bounds,
			    cornerRadius: radius).CGPath
			view.layer.shadowOffset = CGSize(width: 0, height: 0)
			view.layer.shadowOpacity = 1.0
			view.layer.masksToBounds = true
			view.clipsToBounds = false
		}
	}

Below is the result in the simulator. Note that the light-blue empty element is a plain UIView.

shadow and rounded corners uikit.png

As you can see, adding shadow and rounded corners doesn't work on UIImageView, UITextField and UIToolbar. It does work on a plain UIView, UIButton, UITextView and UIDatePicker.

2014-11-18 Swift optionals

Recently I dived into Swift and in order to grok optionals, first read this article on Medium: Swift Optionals and then this comment on Stack Overflow.

2014-11-06 From mov to animated gif

On OS X, the standard QuickTime Player application can record (a part of) your screen, or record the screen of an iOS device over the lightning cable.

You then get a .mov file. You can convert this into an animated gif of slightly smaller size with ffmpeg. You'll need to install homebrew first, and using the brew command, install ffmpeg as follows:

 $ brew install ffmpeg

Then open a terminal and change to the desktop folder or wherever you saved the movie file, and issue the following command:

 $ ffmpeg -i demo.mov -r 15 demo.gif

Drag the resulting demo.gif to Safari to view it. The quality is pretty bad, but hey, animated gifs are all the rage nowadays.

2014-10-18 Remapping your keyboard in OS X Yosemite

If you want to remap your notebook's or external keyboard, there's an excellent and free choice available: Karabiner from the friendly Takayama Fumihiko.

Upon upgrading OS X yesterday, I found it worked straight away in Yosemite as well.

Besides remapping the obvious keys, if you would like to remap that useless Caps Lock key on OS X, get Seil.

2014-10-09

On iOS 8, user permission is required for scheduling local notifications (of class UILocalNotification). Here's an Objective-C example.

To check whether you have permission:

  - (BOOL)appHasPermissionForLocalNotifications
  {
      UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
      if(settings.types & (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge)) {
          NSLog(@"Permission present: 0x%ulX", settings.types);
          return YES;
      } else {
          NSLog(@"Permission not present: 0x%ulX", settings.types);
          return NO;
      }
  }

To request permission:

  [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

2014-09-26 Tomcat error on Ubuntu 14.04

If you upgraded Ubuntu to 14.04 and you've got Tomcat running, chances are that you get the following error in catalina.out:

 SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-bio-80"]
 java.net.SocketException: No such file or directory

Solution is here:
Tomcat7 bind to port 80 fails in ubuntu 14.04lts

2014-09-03 iStat Menus 5

Bjango released iStat Menus 5. I really like this app, but found a minor issue today. I've already sent the folks an e-mail, but for the sake of the internet, I'm documenting it here as well.

iStat Menus can show a graph of your CPU usage along with a nice quick lookup table with the most busy process. It seems it tries to do something helpful with the process name, but in the case of ClamXav, a free and open source virus scanner, it says: ScheduleHelper. The process name in Activity Monitor is more to the point: clamscan.

istat menus process comparison.png

2014-07-25

Today, I found out that on Debian Wheezy, when using XFCE on the desktop and accessed via VNC, the Tab key is disabled for some reason.

Solution is here.

2014-07-11 Xauthority doesn't exist

If you're connecting via SSH from OS X to Linux, you might get the following error:

  /opt/X11/bin/xauth:  file /Users/yourusername/.Xauthority does not exist

You can fix this by installing (or just running) XQuartz, available here.

2014-07-10 Unattended upgrades

I'm not normally prone to linking to stuff, but this is just too good:

http://www.howtoforge.com/how-to-configure-automatic-updates-on-debian-wheezy

Explains how you can get your Debian Wheezy box to automatically update. While this is bad practice for some situations like fragile production boxes, there's plenty of spaces where automatic updates work great: single-purpose machines like your (secondary) DNS, lonely virtual private servers with your home page, etc.

2014-05-16 VNC on Debian Wheezy

I recently discovered that VNC on Debian Wheezy is a bit of a mess.

VNC can be used in two modes: to mirror the actively running instance of X (i.e. the display on :0), or to have X running headless, in any resolution ("geometry") you want, on :1, :2, etc.

The version that comes with Wheezy by default, is an old version of TightVNC server. It doesn't support the alpha channel, so modern desktops like KDE 4 will look pretty bad.

Development has stopped on TightVNC, and continues in the TigerVNC project. There are packages available here, but these are pretty old now: version 1.1, while development has passed 1.3.

In and of itself that wouldn't be a problem, except the 1.1 version has a horrible bug where moving a window to the left will result in display artifacts.

You may also have found TurboVNC. Development seems to move slower but they do provide Debian packages. Unfortunately, even for the latest version it seems it suffers from the same bug.

There's a couple of options:

  • Build TightVNC yourself from the source files in the TigerVNC SourceForge downloads section. I tried this, and it's pretty daunting. I gave up after an hour of futzing.
  • Get the generic, statically linked binaries from the TigerVNC SourceForge downloads section, and then just unpack these in your filesystem root. This dumps some binaries here and there, and your sysadmin (or you yourself) will definitely consider this abuse of the sudo command.
  • Use the old TightVNC 1.1 version, which is nicely packaged, and live with the obvious bugs. Note that the above mentioned bug doesn't seem to manifest itself when exporting the currently running display on :0. On our in-house built software however, there's another issue where portions of the screen sometimes don't refresh.

I'm currently looking at other solutions such as X2Go, which seems to provide decent packages.

Edit 2014-08-26: For the last two months or so, I started using the standard VNC again, and I've switched to XFCE as the desktop environment. This solves most problems, except you run into an easily fixable bug: the tab key doesn't work to auto-complete. This link
solves the problem.

2014-05-07 Debian Wheezy interface without an IP address

Today, I needed to configure a machine so it brought up its ethernet interfaces without an IP address.

This is useful if you use such an interface with plain ethernet packets. For example, network sniffing or bridging stuff, but also when you communicate with custom electronics that speak plain ethernet.

To configure Debian Wheezy to bring up these interfaces without assigning an IP address, add the following stanza to /etc/network/interfaces:

 auto eth1
 iface eth1 inet static
 address 0.0.0.0

You might also want to remove any IPv6 addresses from these interfaces. Stack Overflow told me to add the following line for each interface to /etc/network/interfaces:

 net.ipv6.conf.<interface>.disable_ipv6 = 1

2014-04-16 Python vi keybindings on OS X

If you're used to vi keybindings, and you use Python interactively, you're going to do a lot of cursing on OS X. This is because the readline library (responsible for keybindings and history) is GPL licensed and thus not distributed by Apple.

Here's a quick fix.

Add a file called .editrc with the following content:

 bind -v

Add a file called .pythonrc with the following lines:

 import rlcompleter
 import readline

Add a line to your .bashrc which makes Python run .pythonrc when it starts interactively:

 export PYTHONSTARTUP="$HOME/.pythonrc"

Start python from the commandline and voilĂ , enjoy history and vi keybindings and all that good stuff. Tested on 10.9.2 (Mountain Lion).

2014-01-29 tmux and X11

Recently I've been playing around with tmux . For all you neckbeards, that's the modern equivalent of GNU Screen.

On the surface, it looks pretty cool. Especially because iTerm2 can talk to tmux. From the iTerm2 wiki: When you run "tmux -CC", a new tmux session is created. An iTerm2 window opens and it acts like a normal iTerm2 window. The difference is that when iTerm2 quits or the ssh session is lost, tmux keeps running. You can return to the host you were ssh'ed into and run "tmux -CC attach" and the iTerm2 windows will reopen in the same state they were in before.

That's pretty useful!

A problem that I'm now bumping into, is that when I'm SSH'ing into the remote machine where tmux runs, I'm forwarding X11. This is useful because vim supports the X11 clipboard. That way, if I copy text from vim and paste it on my local machine, layout is retained.

Without the X11 clipboard, I'd have to simply "hard-copy" whatever is on the terminal screen. Vim's line numbers will be copied along. I also couldn't copy more than one screen.

In order to make this work, when ssh opens a session and starts the shell, it sets the environment variable $DISPLAY. Vim then reads it when it starts.

However when you detach tmux, log out and log in again via ssh, DISPLAY is set again to some other value. All shells in your tmux session now have an old/stale value in DISPLAY. Tmux has some commands for this, but it's not automatic. And if that would work, vim has to be restarted again as well.

It would be nice if you could simply configure the DISPLAY variable but this doesn't work -- the ssh server has an option called X11DisplayOffset but the client doesn't. So there's no way to configure this based on the user.

In summary: X11 forwarding and tmux don't work very well.