diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -10,7 +10,7 @@
     'conpherence.pkg.css' => 'e68cf1fa',
     'conpherence.pkg.js' => 'b5b51108',
     'core.pkg.css' => 'fe4effd6',
-    'core.pkg.js' => '5d80e0db',
+    'core.pkg.js' => '396dee49',
     'darkconsole.pkg.js' => '1f9a31bc',
     'differential.pkg.css' => '45951e9e',
     'differential.pkg.js' => 'b71b8c5d',
@@ -375,9 +375,9 @@
     'rsrc/image/texture/table_header_tall.png' => 'd56b434f',
     'rsrc/js/application/aphlict/Aphlict.js' => 'e1d4b11a',
     'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'caade6f2',
-    'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '3c547a81',
+    'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'a14cbdfc',
     'rsrc/js/application/aphlict/behavior-aphlict-status.js' => '5e2634b9',
-    'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'd5a2d665',
+    'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => '27ca6289',
     'rsrc/js/application/calendar/behavior-day-view.js' => '4b3c4443',
     'rsrc/js/application/calendar/behavior-event-all-day.js' => 'b41537c9',
     'rsrc/js/application/calendar/behavior-month-view.js' => 'fe33e256',
@@ -468,7 +468,7 @@
     'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2',
     'rsrc/js/core/KeyboardShortcutManager.js' => 'c19dd9b9',
     'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
-    'rsrc/js/core/Notification.js' => 'ccf1cbf8',
+    'rsrc/js/core/Notification.js' => '5c3349b2',
     'rsrc/js/core/Prefab.js' => 'c5af80a2',
     'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
     'rsrc/js/core/TextAreaUtils.js' => '320810c8',
@@ -587,7 +587,7 @@
     'javelin-aphlict' => 'e1d4b11a',
     'javelin-behavior' => '61cbc29a',
     'javelin-behavior-aphlict-dropdown' => 'caade6f2',
-    'javelin-behavior-aphlict-listen' => '3c547a81',
+    'javelin-behavior-aphlict-listen' => 'a14cbdfc',
     'javelin-behavior-aphlict-status' => '5e2634b9',
     'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
     'javelin-behavior-aphront-drag-and-drop-textarea' => '484a6e22',
@@ -612,7 +612,7 @@
     'javelin-behavior-dashboard-query-panel-select' => '453c5375',
     'javelin-behavior-dashboard-tab-panel' => 'd4eecc63',
     'javelin-behavior-day-view' => '4b3c4443',
-    'javelin-behavior-desktop-notifications-control' => 'd5a2d665',
+    'javelin-behavior-desktop-notifications-control' => '27ca6289',
     'javelin-behavior-detect-timezone' => '4c193c96',
     'javelin-behavior-device' => 'bb1dd507',
     'javelin-behavior-diff-preview-link' => '051c7832',
@@ -791,7 +791,7 @@
     'phabricator-keyboard-shortcut-manager' => 'c19dd9b9',
     'phabricator-main-menu-view' => '16053029',
     'phabricator-nav-view-css' => 'faf6a6fc',
-    'phabricator-notification' => 'ccf1cbf8',
+    'phabricator-notification' => '5c3349b2',
     'phabricator-notification-css' => '3f6c89c9',
     'phabricator-notification-menu-css' => '73fefdfa',
     'phabricator-object-selector-css' => '85ee8ce6',
@@ -1058,6 +1058,13 @@
       'phabricator-drag-and-drop-file-upload',
       'javelin-workboard-board',
     ),
+    '27ca6289' => array(
+      'javelin-behavior',
+      'javelin-stratcom',
+      'javelin-dom',
+      'javelin-uri',
+      'phabricator-notification',
+    ),
     '2926fff2' => array(
       'javelin-behavior',
       'javelin-dom',
@@ -1115,20 +1122,6 @@
       'javelin-dom',
       'javelin-magical-init',
     ),
-    '3c547a81' => array(
-      'javelin-behavior',
-      'javelin-aphlict',
-      'javelin-stratcom',
-      'javelin-request',
-      'javelin-uri',
-      'javelin-dom',
-      'javelin-json',
-      'javelin-router',
-      'javelin-util',
-      'javelin-leader',
-      'javelin-sound',
-      'phabricator-notification',
-    ),
     '3cb0b2fc' => array(
       'javelin-behavior',
       'javelin-dom',
@@ -1338,6 +1331,13 @@
       'javelin-vector',
       'javelin-dom',
     ),
+    '5c3349b2' => array(
+      'javelin-install',
+      'javelin-dom',
+      'javelin-stratcom',
+      'javelin-util',
+      'phabricator-notification-css',
+    ),
     '5c54cbf3' => array(
       'javelin-behavior',
       'javelin-stratcom',
@@ -1676,6 +1676,20 @@
       'javelin-util',
       'phabricator-keyboard-shortcut',
     ),
+    'a14cbdfc' => array(
+      'javelin-behavior',
+      'javelin-aphlict',
+      'javelin-stratcom',
+      'javelin-request',
+      'javelin-uri',
+      'javelin-dom',
+      'javelin-json',
+      'javelin-router',
+      'javelin-util',
+      'javelin-leader',
+      'javelin-sound',
+      'phabricator-notification',
+    ),
     'a37126bd' => array(
       'javelin-install',
       'javelin-dom',
@@ -1951,13 +1965,6 @@
     'cae95e89' => array(
       'syntax-default-css',
     ),
-    'ccf1cbf8' => array(
-      'javelin-install',
-      'javelin-dom',
-      'javelin-stratcom',
-      'javelin-util',
-      'phabricator-notification-css',
-    ),
     'cd2b9b77' => array(
       'phui-oi-list-view-css',
     ),
@@ -1996,13 +2003,6 @@
       'javelin-dom',
       'javelin-stratcom',
     ),
-    'd5a2d665' => array(
-      'javelin-behavior',
-      'javelin-stratcom',
-      'javelin-dom',
-      'javelin-uri',
-      'phabricator-notification',
-    ),
     'd6a7e717' => array(
       'multirow-row-manager',
       'javelin-install',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2647,8 +2647,6 @@
     'PhabricatorDebugController' => 'applications/system/controller/PhabricatorDebugController.php',
     'PhabricatorDefaultRequestExceptionHandler' => 'aphront/handler/PhabricatorDefaultRequestExceptionHandler.php',
     'PhabricatorDefaultSyntaxStyle' => 'infrastructure/syntax/PhabricatorDefaultSyntaxStyle.php',
-    'PhabricatorDesktopNotificationsSetting' => 'applications/settings/setting/PhabricatorDesktopNotificationsSetting.php',
-    'PhabricatorDesktopNotificationsSettingsPanel' => 'applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php',
     'PhabricatorDestructibleCodex' => 'applications/system/codex/PhabricatorDestructibleCodex.php',
     'PhabricatorDestructibleCodexInterface' => 'applications/system/interface/PhabricatorDestructibleCodexInterface.php',
     'PhabricatorDestructibleInterface' => 'applications/system/interface/PhabricatorDestructibleInterface.php',
@@ -3214,6 +3212,8 @@
     'PhabricatorNotificationTestFeedStory' => 'applications/notification/feed/PhabricatorNotificationTestFeedStory.php',
     'PhabricatorNotificationUIExample' => 'applications/uiexample/examples/PhabricatorNotificationUIExample.php',
     'PhabricatorNotificationsApplication' => 'applications/notification/application/PhabricatorNotificationsApplication.php',
+    'PhabricatorNotificationsSetting' => 'applications/settings/setting/PhabricatorNotificationsSetting.php',
+    'PhabricatorNotificationsSettingsPanel' => 'applications/settings/panel/PhabricatorNotificationsSettingsPanel.php',
     'PhabricatorNuanceApplication' => 'applications/nuance/application/PhabricatorNuanceApplication.php',
     'PhabricatorOAuth1AuthProvider' => 'applications/auth/provider/PhabricatorOAuth1AuthProvider.php',
     'PhabricatorOAuth1SecretTemporaryTokenType' => 'applications/auth/provider/PhabricatorOAuth1SecretTemporaryTokenType.php',
@@ -7952,8 +7952,6 @@
     'PhabricatorDebugController' => 'PhabricatorController',
     'PhabricatorDefaultRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
     'PhabricatorDefaultSyntaxStyle' => 'PhabricatorSyntaxStyle',
-    'PhabricatorDesktopNotificationsSetting' => 'PhabricatorInternalSetting',
-    'PhabricatorDesktopNotificationsSettingsPanel' => 'PhabricatorSettingsPanel',
     'PhabricatorDestructibleCodex' => 'Phobject',
     'PhabricatorDestructionEngine' => 'Phobject',
     'PhabricatorDestructionEngineExtension' => 'Phobject',
@@ -8577,6 +8575,8 @@
     'PhabricatorNotificationTestFeedStory' => 'PhabricatorFeedStory',
     'PhabricatorNotificationUIExample' => 'PhabricatorUIExample',
     'PhabricatorNotificationsApplication' => 'PhabricatorApplication',
+    'PhabricatorNotificationsSetting' => 'PhabricatorInternalSetting',
+    'PhabricatorNotificationsSettingsPanel' => 'PhabricatorSettingsPanel',
     'PhabricatorNuanceApplication' => 'PhabricatorApplication',
     'PhabricatorOAuth1AuthProvider' => 'PhabricatorOAuthAuthProvider',
     'PhabricatorOAuth1SecretTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
diff --git a/src/applications/notification/builder/PhabricatorNotificationBuilder.php b/src/applications/notification/builder/PhabricatorNotificationBuilder.php
--- a/src/applications/notification/builder/PhabricatorNotificationBuilder.php
+++ b/src/applications/notification/builder/PhabricatorNotificationBuilder.php
@@ -145,13 +145,16 @@
     $dict = array();
 
     $viewer = $this->user;
-    $desktop_key = PhabricatorDesktopNotificationsSetting::SETTINGKEY;
-    $desktop_enabled = $viewer->getUserSetting($desktop_key);
+    $key = PhabricatorNotificationsSetting::SETTINGKEY;
+    $setting = $viewer->getUserSetting($key);
+    $desktop_ready = PhabricatorNotificationsSetting::desktopReady($setting);
+    $web_ready = PhabricatorNotificationsSetting::webReady($setting);
 
     foreach ($stories as $story) {
       if ($story instanceof PhabricatorApplicationTransactionFeedStory) {
         $dict[] = array(
-          'desktopReady' => $desktop_enabled,
+          'desktopReady' => $desktop_ready,
+          'webReady'     => $web_ready,
           'title'        => $story->renderText(),
           'body'         => $story->renderTextBody(),
           'href'         => $story->getURI(),
@@ -159,7 +162,8 @@
         );
       } else if ($story instanceof PhabricatorNotificationTestFeedStory) {
         $dict[] = array(
-          'desktopReady' => $desktop_enabled,
+          'desktopReady' => $desktop_ready,
+          'webReady'     => $web_ready,
           'title'        => pht('Test Notification'),
           'body'         => $story->renderText(),
           'href'         => null,
@@ -168,6 +172,7 @@
       } else {
         $dict[] = array(
           'desktopReady' => false,
+          'webReady'     => false,
           'title'        => null,
           'body'         => null,
           'href'         => null,
diff --git a/src/applications/notification/controller/PhabricatorNotificationIndividualController.php b/src/applications/notification/controller/PhabricatorNotificationIndividualController.php
--- a/src/applications/notification/controller/PhabricatorNotificationIndividualController.php
+++ b/src/applications/notification/controller/PhabricatorNotificationIndividualController.php
@@ -42,6 +42,7 @@
       'pertinent'         => true,
       'primaryObjectPHID' => $story->getPrimaryObjectPHID(),
       'desktopReady'      => $data['desktopReady'],
+      'webReady'          => $data['webReady'],
       'href'              => $data['href'],
       'icon'              => $data['icon'],
       'title'             => $data['title'],
diff --git a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php b/src/applications/settings/panel/PhabricatorNotificationsSettingsPanel.php
rename from src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php
rename to src/applications/settings/panel/PhabricatorNotificationsSettingsPanel.php
--- a/src/applications/settings/panel/PhabricatorDesktopNotificationsSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorNotificationsSettingsPanel.php
@@ -1,6 +1,6 @@
 <?php
 
-final class PhabricatorDesktopNotificationsSettingsPanel
+final class PhabricatorNotificationsSettingsPanel
   extends PhabricatorSettingsPanel {
 
   public function isEnabled() {
@@ -14,11 +14,11 @@
   }
 
   public function getPanelKey() {
-    return 'desktopnotifications';
+    return 'notifications';
   }
 
   public function getPanelName() {
-    return pht('Desktop Notifications');
+    return pht('Notifications');
   }
 
   public function getPanelGroupKey() {
@@ -29,7 +29,7 @@
     $viewer = $this->getViewer();
     $preferences = $this->getPreferences();
 
-    $notifications_key = PhabricatorDesktopNotificationsSetting::SETTINGKEY;
+    $notifications_key = PhabricatorNotificationsSetting::SETTINGKEY;
     $notifications_value = $preferences->getSettingValue($notifications_key);
 
     if ($request->isFormPost()) {
@@ -43,7 +43,7 @@
         ->setURI($this->getPanelURI('?saved=true'));
     }
 
-    $title = pht('Desktop Notifications');
+    $title = pht('Notifications');
     $control_id = celerity_generate_unique_node_id();
     $status_id = celerity_generate_unique_node_id();
     $browser_status_id = celerity_generate_unique_node_id();
@@ -97,19 +97,31 @@
         'id' => $message_id,
       ));
 
+    $saved_box = null;
+    if ($request->getBool('saved')) {
+      $saved_box = id(new PHUIInfoView())
+        ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
+        ->appendChild(pht('Changes saved.'));
+    }
+
     $status_box = id(new PHUIInfoView())
       ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
       ->setID($status_id)
       ->setIsHidden(true)
       ->appendChild($message_container);
 
+    $status_box = id(new PHUIBoxView())
+      ->addClass('mll mlr')
+      ->appendChild($status_box);
+
     $control_config = array(
        'controlID' => $control_id,
        'statusID' => $status_id,
        'messageID' => $message_id,
        'browserStatusID' => $browser_status_id,
        'defaultMode' => 0,
-       'desktopMode' => 1,
+       'desktop' => 1,
+       'desktopOnly' => 2,
        'cancelAsk' => $cancel_ask,
        'grantedAsk' => $accept_ask,
        'deniedAsk' => $reject_ask,
@@ -127,16 +139,12 @@
         ->setControlID($control_id)
         ->setName($notifications_key)
         ->setValue($notifications_value)
-        ->setOptions(
-          array(
-            1 => pht('Send Desktop Notifications Too'),
-            0 => pht('Send Application Notifications Only'),
-          ))
+        ->setOptions(PhabricatorNotificationsSetting::getOptionsMap())
         ->setCaption(
           pht(
-            'Should Phabricator send desktop notifications? These are sent '.
-            'in addition to the notifications within the Phabricator '.
-            'application.'))
+            'Phabricator can send real-time notifications to your web browser '.
+            'or to your desktop. Select where you\'d want to receive these '.
+            'real-time updates.'))
         ->initBehavior(
           'desktop-notifications-control',
           $control_config))
@@ -154,12 +162,14 @@
     $form_box = id(new PHUIObjectBoxView())
       ->setHeader(
         id(new PHUIHeaderView())
-        ->setHeader(pht('Desktop Notifications'))
+        ->setHeader(pht('Notifications'))
         ->addActionLink($test_button))
-      ->setForm($form)
       ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
-      ->setInfoView($status_box)
-      ->setFormSaved($request->getBool('saved'));
+      ->appendChild(array(
+        $saved_box,
+        $status_box,
+        $form,
+      ));
 
     $browser_status_box = id(new PHUIInfoView())
       ->setID($browser_status_id)
diff --git a/src/applications/settings/setting/PhabricatorDesktopNotificationsSetting.php b/src/applications/settings/setting/PhabricatorDesktopNotificationsSetting.php
deleted file mode 100644
--- a/src/applications/settings/setting/PhabricatorDesktopNotificationsSetting.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-final class PhabricatorDesktopNotificationsSetting
-  extends PhabricatorInternalSetting {
-
-  const SETTINGKEY = 'desktop-notifications';
-
-  public function getSettingName() {
-    return pht('Desktop Notifications');
-  }
-
-}
diff --git a/src/applications/settings/setting/PhabricatorNotificationsSetting.php b/src/applications/settings/setting/PhabricatorNotificationsSetting.php
new file mode 100644
--- /dev/null
+++ b/src/applications/settings/setting/PhabricatorNotificationsSetting.php
@@ -0,0 +1,44 @@
+<?php
+
+final class PhabricatorNotificationsSetting
+  extends PhabricatorInternalSetting {
+
+  const SETTINGKEY = 'desktop-notifications';
+
+  const WEB_ONLY = 0;
+  const WEB_AND_DESKTOP = 1;
+  const DESKTOP_ONLY = 2;
+  const NONE = 3;
+
+  public function getSettingName() {
+    return pht('Notifications');
+  }
+
+  public static function getOptionsMap() {
+    return array(
+      self::WEB_ONLY => pht('Web Only'),
+      self::WEB_AND_DESKTOP => pht('Web and Desktop'),
+      self::DESKTOP_ONLY => pht('Desktop Only'),
+      self::NONE => pht('No Notifications'),
+    );
+  }
+
+  public static function desktopReady($option) {
+    switch ($option) {
+      case self::WEB_AND_DESKTOP:
+      case self::DESKTOP_ONLY:
+        return true;
+    }
+    return false;
+  }
+
+  public static function webReady($option) {
+    switch ($option) {
+      case self::WEB_AND_DESKTOP:
+      case self::WEB_ONLY:
+        return true;
+    }
+    return false;
+  }
+
+}
diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
--- a/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
+++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
@@ -82,6 +82,7 @@
     new JX.Notification()
       .setContent(JX.$H(response.content))
       .setDesktopReady(response.desktopReady)
+      .setWebReady(response.webReady)
       .setKey(response.primaryObjectPHID)
       .setTitle(response.title)
       .setBody(response.body)
diff --git a/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js b/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js
--- a/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js
+++ b/webroot/rsrc/js/application/aphlict/behavior-desktop-notifications-control.js
@@ -84,12 +84,12 @@
           return;
         }
         var value = e.getTarget().value;
-        if (value == config.desktopMode) {
-          window.Notification.requestPermission(
-            function (permission) {
-              updateFormStatus(permission);
-              updateBrowserStatus(permission);
-            });
+        if ((value == config.desktop) || (value == config.desktopOnly)) {
+            window.Notification.requestPermission(
+              function (permission) {
+                updateFormStatus(permission);
+                updateBrowserStatus(permission);
+              });
         } else {
           var statusEl = JX.$(config.statusID);
           JX.DOM.hide(statusEl);
diff --git a/webroot/rsrc/js/core/Notification.js b/webroot/rsrc/js/core/Notification.js
--- a/webroot/rsrc/js/core/Notification.js
+++ b/webroot/rsrc/js/core/Notification.js
@@ -27,6 +27,7 @@
     _hideTimer : null,
     _duration : 12000,
     _desktopReady : false,
+    _webReady : false,
     _key : null,
     _title : null,
     _body : null,
@@ -35,6 +36,12 @@
 
     show : function() {
       var self = JX.Notification;
+
+      // This person doesn't like any real-time notification
+      if (!this._desktopReady && !this._webReady) {
+        return;
+      }
+
       if (!this._visible) {
         this._visible = true;
 
@@ -92,6 +99,11 @@
       return this;
     },
 
+    setWebReady : function(ready) {
+      this._webReady = ready;
+      return this;
+    },
+
     setTitle : function(title) {
       this._title = title;
       return this;