diff --git a/app/main.cpp b/app/main.cpp
index 158c189..61bd8be 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -40,6 +40,7 @@ int main(int argc, char *argv[])
   qInstallMessageHandler(DebugHandler);
 
   QApplication a(argc, argv);
+  a.setApplicationName(QCoreApplication::translate("main", "SI Editor"));
 
   MainWindow w;
 
diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp
index 2fa47fc..d783532 100644
--- a/app/mainwindow.cpp
+++ b/app/mainwindow.cpp
@@ -1,5 +1,6 @@
 #include "mainwindow.h"
 
+#include <QApplication>
 #include <QFileDialog>
 #include <QLineEdit>
 #include <QMenuBar>
@@ -104,7 +105,7 @@ MainWindow::MainWindow(QWidget *parent) :
 
   splitter->setSizes({99999, 99999});
 
-  setWindowTitle(tr("SI Editor"));
+  setWindowTitle(QApplication::applicationName());
 }
 
 void MainWindow::OpenFilename(const QString &s)
@@ -176,6 +177,12 @@ void MainWindow::SetPanel(Panel *panel, si::Object *chunk)
   }
 }
 
+void MainWindow::UpdateWindowTitle(QString filename)
+{
+  TrimOffDirectory(filename);
+  setWindowTitle(QStringLiteral("%1 - %2[*]").arg(QApplication::applicationName(), filename));
+}
+
 void MainWindow::ExtractObject(si::Object *obj)
 {
   QString filename = QString::fromStdString(obj->filename());
@@ -183,11 +190,7 @@ void MainWindow::ExtractObject(si::Object *obj)
     filename = QString::fromStdString(obj->name());
     filename.append(QStringLiteral(".bin"));
   } else {
-    // Strip off directory
-    int index = filename.lastIndexOf('\\');
-    if (index != -1) {
-      filename = filename.mid(index+1);
-    }
+    TrimOffDirectory(filename);
   }
 
   QString s = QFileDialog::getSaveFileName(this, tr("Export Object"), filename);
@@ -216,6 +219,8 @@ void MainWindow::ReplaceObject(si::Object *obj)
 #endif
         )) {
       static_cast<Panel*>(config_stack_->currentWidget())->ResetData();
+      setWindowModified(true);
+
     } else {
       QMessageBox::critical(this, QString(), tr("Failed to open to file \"%1\".").arg(s));
     }
@@ -278,11 +283,26 @@ bool MainWindow::ExtractAllRecursiveInternal(const QDir &dir, const si::Core *ob
   return true;
 }
 
+void MainWindow::TrimOffDirectory(QString& s)
+{
+  int bSlashIndex = s.lastIndexOf('\\');
+  int fSlashIndex = s.lastIndexOf('/');
+  int lastIndex = (bSlashIndex > fSlashIndex) ? bSlashIndex : fSlashIndex;
+
+  if (lastIndex != -1) {
+    s = s.mid(lastIndex + 1);
+  }
+}
+
 void MainWindow::NewFile()
 {
+  tree_->clearSelection();
+  SetPanel(panel_blank_, nullptr);
   model_.SetCore(nullptr);
   interleaf_.Clear();
   model_.SetCore(&interleaf_);
+
+  UpdateWindowTitle(tr("UNTITLED.SI"));
 }
 
 void MainWindow::OpenFile()
@@ -290,6 +310,7 @@ void MainWindow::OpenFile()
   QString s = GetOpenFileName();
   if (!s.isEmpty()) {
     OpenFilename(s);
+    UpdateWindowTitle(s);
   }
 }
 
@@ -307,6 +328,7 @@ bool MainWindow::SaveFile()
     );
 
     if (r == Interleaf::ERROR_SUCCESS) {
+      UpdateWindowTitle(current_filename_);
       return true;
     } else {
       QMessageBox::critical(this, QString(), tr("Failed to write SI file: %1").arg(r));
diff --git a/app/mainwindow.h b/app/mainwindow.h
index cb8c99e..ee99b52 100644
--- a/app/mainwindow.h
+++ b/app/mainwindow.h
@@ -39,6 +39,10 @@ private:
 
   bool ExtractAllRecursiveInternal(const QDir &dir, const si::Core *obj);
 
+  void TrimOffDirectory(QString &s);
+
+  void UpdateWindowTitle(QString filename);
+
   static const QString kFileFilter;
 
   QStackedWidget *config_stack_;