diff --git a/Cargo.toml b/Cargo.toml
index 9e6afc8218e6cea2eda4e87465e8602f3efc6f8d..f33462407cd3fde00ac1eb2ad69932e82cd44243 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,7 +47,7 @@ path = "src/viewer/main.rs"
 html5ever = "0.12"
 html5ever-atoms = "0.1"
 #mime_guess = "1.8"
-orbclient = "0.2"
+orbclient = "0.3"
 orbfont = "0.1"
 orbimage = "0.1"
 orbtk = "0.2"
diff --git a/src/browser/main.rs b/src/browser/main.rs
index 02dfbc3cc13bee48b2dbeb51b3099e5444e95b3f..fed8fbb62969344638619ee87c4f3597286c1c68 100644
--- a/src/browser/main.rs
+++ b/src/browser/main.rs
@@ -22,7 +22,7 @@ use std::sync::Arc;
 
 use html5ever::parse_document;
 use html5ever::rcdom::{Document, Doctype, Text, Comment, Element, RcDom, Handle};
-use orbclient::{Color, Renderer, Window, EventOption, K_BKSP, K_ESC, K_LEFT, K_RIGHT, K_DOWN, K_PGDN, K_UP, K_PGUP};
+use orbclient::{Color, EventOption, Renderer, Window, WindowFlag, K_BKSP, K_ESC, K_LEFT, K_RIGHT, K_DOWN, K_PGDN, K_UP, K_PGUP};
 use orbfont::Font;
 use tendril::TendrilSink;
 use url::Url;
@@ -610,7 +610,9 @@ fn main_window(arg: &str, font: &Font, font_bold: &Font) {
 
     let window_w = 800;
     let window_h = 600;
-    let mut window = Window::new(-1, -1, window_w as u32, window_h as u32,  "Browser").unwrap();
+    let mut window = Window::new_flags(
+        -1, -1, window_w as u32, window_h as u32,  "Browser", &[WindowFlag::Resizable]
+    ).unwrap();
 
     let mut anchors = BTreeMap::new();
     let mut blocks = Vec::new();
@@ -626,7 +628,21 @@ fn main_window(arg: &str, font: &Font, font_bold: &Font) {
         if reload {
             reload = false;
 
-            window.set_title(&format!("Browser ({})", url));
+            window.set_title(&format!("{} - Browser", url));
+
+            anchors.clear();
+            blocks.clear();
+            text_block("Loading...", &mut 0, &mut 0, 16.0, true, Color::rgb(0, 0, 0), None, font, font_bold, &mut blocks);
+
+            {
+                window.set(Color::rgb(255, 255, 255));
+
+                for block in blocks.iter() {
+                    block.draw(&mut window, (0, 0));
+                }
+
+                window.sync();
+            }
 
             anchors.clear();
             blocks.clear();
@@ -634,7 +650,6 @@ fn main_window(arg: &str, font: &Font, font_bold: &Font) {
 
             offset = (0, 0);
             max_offset = (0, 0);
-
             for block in blocks.iter() {
                 if block.x + block.w > max_offset.0 {
                     max_offset.0 = block.x + block.w;
@@ -732,6 +747,15 @@ fn main_window(arg: &str, font: &Font, font_bold: &Font) {
                         }
                     }
                 },
+                EventOption::Scroll(scroll_event) => {
+                    offset.0 = cmp::max(0, cmp::min(cmp::max(0, max_offset.0 - window_w), offset.0 - scroll_event.x * 48));
+                    offset.1 = cmp::max(0, cmp::min(cmp::max(0, max_offset.1 - window_h), offset.1 - scroll_event.y * 48));
+
+                    redraw = true;
+                },
+                EventOption::Resize(_) => {
+                    redraw = true;
+                },
                 EventOption::Quit(_) => return,
                 _ => ()
             }
diff --git a/src/terminal/console.rs b/src/terminal/console.rs
index a1cb89b963856e93701151a48e9093b5795b6076..9407dc1e4a11f3837dc87b6a8995d1b2a49c8b22 100644
--- a/src/terminal/console.rs
+++ b/src/terminal/console.rs
@@ -4,7 +4,7 @@ use std::cmp;
 use std::collections::{BTreeSet, VecDeque};
 use std::io::Result;
 
-use orbclient::{Color, Event, EventOption, Renderer, Window};
+use orbclient::{Color, Event, EventOption, Renderer, Window, WindowFlag};
 use orbfont::Font;
 
 #[cfg(target_arch = "x86_64")]
@@ -46,7 +46,7 @@ pub struct Console {
 
 impl Console {
     pub fn new(width: u32, height: u32) -> Console {
-        let mut window = Window::new_flags(-1, -1, width, height, "Terminal", true).unwrap();
+        let mut window = Window::new_flags(-1, -1, width, height, "Terminal", &[WindowFlag::Async]).unwrap();
         window.sync();
         Console {
             console: ransid::Console::new(width as usize / 8, height as usize / 16),
diff --git a/src/viewer/main.rs b/src/viewer/main.rs
index f9821195d75940d3fb973c574537aeebcc7f0f81..d1f11c869e283c54159dc3333fa11a1c90dd5959 100644
--- a/src/viewer/main.rs
+++ b/src/viewer/main.rs
@@ -6,30 +6,49 @@ extern crate orbimage;
 use std::cmp::max;
 use std::env;
 
-use orbclient::{Color, Renderer, Window, EventOption, K_ESC};
+use orbclient::{Color, EventOption, Renderer, Window, WindowFlag};
 use orbimage::Image;
 
-fn event_loop(window: &mut Window){
-    loop {
-        for event in window.events() {
-            if let EventOption::Key(key_event) = event.to_option() {
-                if key_event.pressed && key_event.scancode == K_ESC {
-                    return;
-                }
-            }
-            if let EventOption::Quit(_) = event.to_option() {
-                return;
-            }
-        }
+fn find_scale(image: &Image, width: u32, height: u32) -> (u32, u32, f64) {
+    let d_w = width as f64;
+    let d_h = height as f64;
+    let i_w = image.width() as f64;
+    let i_h = image.height() as f64;
+
+    let scale = if d_w / d_h > i_w / i_h {
+        d_h / i_h
+    } else {
+        d_w / i_w
+    };
+
+    if scale < 1.0 {
+        ((i_w * scale) as u32, (i_h * scale) as u32, scale)
+    } else {
+        (i_w as u32, i_h as u32, 1.0)
     }
 }
 
-fn error_msg(window: &mut Window, msg: &str) {
-    let mut x = 0;
-    for c in msg.chars() {
-        window.char(x, 0, c, Color::rgb(0, 0, 0));
-        x += 8;
+fn draw_image(window: &mut Window, image: &Image) {
+    window.set(Color::rgb(0, 0, 0));
+    /*
+    let box_size = 4;
+    for box_y in 0..window.height()/box_size {
+        for box_x in 0..window.width()/box_size {
+            let color = if box_x % 2 == box_y % 2 {
+                Color::rgb(102, 102, 102)
+            }else{
+                Color::rgb(53, 53, 53)
+            };
+
+            window.rect((box_x * box_size) as i32, (box_y * box_size) as i32, box_size, box_size, color);
+        }
     }
+    */
+
+    let x = (window.width() - image.width())/2;
+    let y = (window.height() - image.height())/2;
+    image.draw(window, x as i32, y as i32);
+    window.sync();
 }
 
 fn main() {
@@ -40,62 +59,69 @@ fn main() {
 
     match Image::from_path(&path) {
         Ok(image) => {
-            let (width, height) = orbclient::get_display_size().expect("viewer: failed to get display size");
-            println!("Display: {}, {}", width, height);
+            let (display_width, display_height) = orbclient::get_display_size().expect("viewer: failed to get display size");
 
-            println!("Image: {}, {}", image.width(), image.height());
+            let (width, height, scale) = find_scale(&image, display_width * 4/5, display_height * 4/5);
 
-            let best_width = width*3/4;
-            let best_height = height*3/4;
+            let mut window = Window::new_flags(
+                -1, -1, max(320, width), max(240, height),
+                &format!("{} - {:.1}% - Viewer", path, scale * 100.0),
+                &[WindowFlag::Resizable]
+            ).unwrap();
 
-            let d_w = best_width as f64;
-            let d_h = best_height as f64;
-            let i_w = image.width() as f64;
-            let i_h = image.height() as f64;
+            let mut scaled_image = image.clone();
+            let mut resize = Some((window.width(), window.height()));
+            loop {
+                if let Some((w, h)) = resize.take() {
+                    let (width, height, scale) = find_scale(&image, w, h);
 
-            let best_scale = if d_w / d_h > i_w / i_h {
-                d_h / i_h
-            } else {
-                d_w / i_w
-            };
+                    if width == scaled_image.width() && height == scaled_image.height() {
+                        // Do not resize scaled image
+                    } else if width == image.width() && height == image.height() {
+                        scaled_image = image.clone();
+                    } else {
+                        scaled_image = image.resize(width, height, orbimage::ResizeType::Lanczos3).unwrap();
+                    }
 
-            let (scaled_image, scale) = if best_scale < 1.0 {
-                (image.resize((i_w * best_scale) as u32, (i_h * best_scale) as u32,
-                             orbimage::ResizeType::Lanczos3).unwrap(), best_scale)
-            } else {
-                (image.clone(), 1.0)
-            };
+                    window.set_title(&format!("{} - {:.1}% - Viewer", path, scale * 100.0));
 
-            let mut window = Window::new(-1, -1, max(320, scaled_image.width()), max(240, scaled_image.height()),
-                                         &format!("{} - {:.1}% - Viewer", path, scale * 100.0)).unwrap();
-
-            let box_size = 4;
-            for box_y in 0..window.height()/box_size {
-                for box_x in 0..window.width()/box_size {
-                    let color = if box_x % 2 == box_y % 2 {
-                        Color::rgb(102, 102, 102)
-                    }else{
-                        Color::rgb(53, 53, 53)
-                    };
+                    draw_image(&mut window, &scaled_image);
+                }
 
-                    window.rect((box_x * box_size) as i32, (box_y * box_size) as i32, box_size, box_size, color);
+                for event in window.events() {
+                    match event.to_option() {
+                        EventOption::Resize(resize_event) => {
+                            resize = Some((resize_event.width, resize_event.height));
+                        },
+                        EventOption::Quit(_) => return,
+                        _ => ()
+                    }
                 }
             }
-
-            let x = (window.width() - scaled_image.width())/2;
-            let y = (window.height() - scaled_image.height())/2;
-            scaled_image.draw(&mut window, x as i32, y as i32);
-            window.sync();
-            event_loop(&mut window);
         },
         Err(err) => {
             let msg = format!("{}", err);
+
             let mut window = Window::new(-1, -1, max(320, msg.len() as u32 * 8), 32,
                                          &format!("{} - Viewer", path)).unwrap();
+
             window.set(Color::rgb(255, 255, 255));
-            error_msg(&mut window, &msg);
+
+            let mut x = 0;
+            for c in msg.chars() {
+                window.char(x, 0, c, Color::rgb(0, 0, 0));
+                x += 8;
+            }
+
             window.sync();
-            event_loop(&mut window);
+
+            loop {
+                for event in window.events() {
+                    if let EventOption::Quit(_) = event.to_option() {
+                        return;
+                    }
+                }
+            }
         }
     }
 }