diff --git a/core/includes/common.inc b/core/includes/common.inc
index 3694182..9447400 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2277,14 +2277,14 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS
     // Don't add settings if there is no other JavaScript on the page, unless
     // this is an AJAX request.
     if (!empty($items['settings']) || $is_ajax) {
-      global $theme_key;
+      $theme = \Drupal::themeNegotiator()->getActiveTheme();
       // Provide the page with information about the theme that's used, so that
       // a later AJAX request can be rendered using the same theme.
       // @see \Drupal\Core\Theme\AjaxBasePageNegotiator
-      $setting['ajaxPageState']['theme'] = $theme_key;
+      $setting['ajaxPageState']['theme'] = $theme;
       // Checks that the DB is available before filling theme_token.
       if (!defined('MAINTENANCE_MODE')) {
-        $setting['ajaxPageState']['theme_token'] = drupal_get_token($theme_key);
+        $setting['ajaxPageState']['theme_token'] = drupal_get_token($theme);
       }
 
       // Provide the page with information about the individual JavaScript files
@@ -4532,9 +4532,9 @@ function drupal_render_cache_by_query($query, $function, $expire = CacheBackendI
  *   $granularity was passed in, more parts are added.
  */
 function drupal_render_cid_parts($granularity = NULL) {
-  global $theme, $base_root, $user;
+  global $base_root, $user;
 
-  $cid_parts[] = $theme;
+  $cid_parts[] = \Drupal::themeNegotiator()->getActiveTheme();
   // If Locale is enabled but we have only one language we do not need it as cid
   // part.
   if (language_multilingual()) {
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 65349a3..310bd7d 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -853,7 +853,7 @@ function drupal_find_theme_templates($cache, $extension, $path) {
       }
     }
   }
-  global $theme;
+  $theme = \Drupal::themeNegotiator()->getActiveTheme();
   $subtheme_paths = isset($theme_paths[$theme]) ? $theme_paths[$theme] : array();
 
   // Escape the periods in the extension.
@@ -2396,7 +2396,7 @@ function theme_get_suggestions($args, $base, $delimiter = '__') {
  * @see system_page_build()
  */
 function template_preprocess_maintenance_page(&$variables) {
-  global $theme;
+  $theme = \Drupal::themeNegotiator()->getActiveTheme();
   $language_interface = language(Language::TYPE_INTERFACE);
   // Retrieve the theme data to list all available regions.
   $theme_data = list_themes();
diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc
index 96dcd2f..8a9d051 100644
--- a/core/includes/theme.maintenance.inc
+++ b/core/includes/theme.maintenance.inc
@@ -20,6 +20,7 @@ function _drupal_maintenance_theme() {
   global $theme, $theme_key, $conf;
 
   // If $theme is already set, assume the others are set too, and do nothing.
+  // @FIXME TF!
   if (isset($theme)) {
     return;
   }
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 9c14801..4bbe413 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -357,6 +357,15 @@ public static function moduleHandler() {
   }
 
   /**
+   * Returns the theme negotiator.
+   *
+   * @return \Drupal\Core\Theme\ThemeNegotiator
+   */
+  public static function themeNegotiator() {
+    return static::$container->get('theme.negotiator');
+  }
+
+  /**
    * Returns the typed data manager service.
    *
    * Use the typed data manager service for creating typed data objects.
diff --git a/core/lib/Drupal/Core/Theme/ThemeNegotiator.php b/core/lib/Drupal/Core/Theme/ThemeNegotiator.php
index 51f3e67..775bd2b 100644
--- a/core/lib/Drupal/Core/Theme/ThemeNegotiator.php
+++ b/core/lib/Drupal/Core/Theme/ThemeNegotiator.php
@@ -118,6 +118,16 @@ public function getActiveTheme() {
   }
 
   /**
+   * Sets the current active theme for the request.
+   *
+   * @param string $theme
+   *   The theme name.
+   */
+  public function setActiveTheme($theme) {
+    $this->request->attributes->set('_theme_active', $theme);
+  }
+
+  /**
    * {@inheritdoc
    */
   public function applies(Request $request) {
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index dd3aa6f..62d7361 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -122,7 +122,7 @@ function block_menu() {
  * Renders blocks into their regions.
  */
 function block_page_build(&$page) {
-  global $theme;
+  $theme = \Drupal::themeNegotiator()->getActiveTheme();
 
   // The theme system might not yet be initialized. We need $theme.
   drupal_theme_initialize();
diff --git a/core/modules/block/lib/Drupal/block/BlockListController.php b/core/modules/block/lib/Drupal/block/BlockListController.php
index 8547ba4..d2ff695 100644
--- a/core/modules/block/lib/Drupal/block/BlockListController.php
+++ b/core/modules/block/lib/Drupal/block/BlockListController.php
@@ -89,7 +89,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
   public function load() {
     // If no theme was specified, use the current theme.
     if (!$this->theme) {
-      $this->theme = $GLOBALS['theme'];
+      $this->theme = \Drupal::themeNegotiator()->getActiveTheme();
     }
 
     // Store the region list.
@@ -119,7 +119,7 @@ public function load() {
   public function render($theme = NULL, Request $request = NULL) {
     $this->request = $request;
     // If no theme was specified, use the current theme.
-    $this->theme = $theme ?: $GLOBALS['theme_key'];
+    $this->theme = $theme ?: \Drupal::themeNegotiator()->getActiveTheme();
 
     return drupal_get_form($this);
   }
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index aaf0ba6..fb0deac 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -60,7 +60,7 @@ function color_form_system_theme_settings_alter(&$form, &$form_state) {
  * Replaces style sheets with color-altered style sheets.
  */
 function color_css_alter(&$css) {
-  global $theme_key;
+  $theme_key = \Drupal::themeNegotiator()->getActiveTheme();
   $themes = list_themes();
 
   // Override stylesheets.
diff --git a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php
index ec76227..0483ac1 100644
--- a/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php
+++ b/core/modules/system/lib/Drupal/system/Form/ThemeSettingsForm.php
@@ -282,8 +282,9 @@ public function buildForm(array $form, array &$form_state, $theme = '') {
       // Save the name of the current theme (if any), so that we can temporarily
       // override the current theme and allow theme_get_setting() to work
       // without having to pass the theme name to it.
-      $default_theme = !empty($GLOBALS['theme_key']) ? $GLOBALS['theme_key'] : NULL;
+      $default_theme = \Drupal::themeNegotiator()->getActiveTheme();
       $GLOBALS['theme_key'] = $theme;
+      \Drupal::themeNegotiator()->setActiveTheme($theme);
 
       // Process the theme and all its base themes.
       foreach ($theme_keys as $theme) {
@@ -303,6 +304,7 @@ public function buildForm(array $form, array &$form_state, $theme = '') {
       // Restore the original current theme.
       if (isset($default_theme)) {
         $GLOBALS['theme_key'] = $default_theme;
+        \Drupal::themeNegotiator()->setActiveTheme($default_theme);
       }
       else {
         unset($GLOBALS['theme_key']);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php
index e8b8201..6450010 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/RegionContentTest.php
@@ -25,7 +25,7 @@ public static function getInfo() {
    * Tests setting and retrieving content for theme regions.
    */
   function testRegions() {
-    global $theme_key;
+    $theme_key = \Drupal::themeNegotiator()->getActiveTheme();
 
     $block_regions = array_keys(system_region_list($theme_key));
     $delimiter = $this->randomName(32);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php
index 492dfd6..2b4f1ac 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeTest.php
@@ -224,6 +224,7 @@ function testListThemes() {
    */
   function testThemeGetSetting() {
     $GLOBALS['theme_key'] = 'test_theme';
+    \Drupal::themeNegotiator()->setActiveTheme('test_theme');
     $this->assertIdentical(theme_get_setting('theme_test_setting'), 'default value', 'theme_get_setting() uses the default theme automatically.');
     $this->assertNotEqual(theme_get_setting('subtheme_override', 'test_basetheme'), theme_get_setting('subtheme_override', 'test_subtheme'), 'Base theme\'s default settings values can be overridden by subtheme.');
     $this->assertIdentical(theme_get_setting('basetheme_only', 'test_subtheme'), 'base theme value', 'Base theme\'s default settings values are inherited by subtheme.');
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index fac4c21..ec378d7 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2825,7 +2825,7 @@ function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $repl
 function system_page_alter(&$page) {
   // Find all non-empty page regions, and add a theme wrapper function that
   // allows them to be consistently themed.
-  $regions = system_region_list($GLOBALS['theme']);
+  $regions = system_region_list(\Drupal::themeNegotiator()->getActiveTheme());
   foreach (array_keys($regions) as $region) {
     if (!empty($page[$region])) {
       $page[$region]['#theme_wrappers'][] = 'region';
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module
index ba8b273..f0cd475 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.module
+++ b/core/modules/system/tests/modules/batch_test/batch_test.module
@@ -388,8 +388,7 @@ function _batch_test_theme_callback() {
   // theme is being used on the batch processing page by viewing that page
   // directly. Instead, we save the theme being used in a variable here, so
   // that it can be loaded and inspected in the thread running the test.
-  global $theme;
-  batch_test_stack($theme);
+  batch_test_stack(\Drupal::themeNegotiator()->getActiveTheme());
 }
 
 /**
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.module b/core/modules/system/tests/modules/menu_test/menu_test.module
index caf216b..b25ce9e 100644
--- a/core/modules/system/tests/modules/menu_test/menu_test.module
+++ b/core/modules/system/tests/modules/menu_test/menu_test.module
@@ -453,11 +453,11 @@ function menu_test_custom_403_404_callback() {
  * @deprecated Use \Drupal\menu_test\Controller\MenuTestController::themePage()
  */
 function menu_test_theme_page_callback($inherited = FALSE) {
-  global $theme_key;
+  $theme_key = \Drupal::themeNegotiator()->getActiveTheme();
   // Initialize the theme system so that $theme_key will be populated.
   drupal_theme_initialize();
   // Now we check what the theme negotiator service returns.
-  $active_theme = \Drupal::service('theme.negotiator')->getActiveTheme('getActiveTheme');
+  $active_theme = \Drupal::themeNegotiator()->getActiveTheme();
   $output = "Active theme: $active_theme. Actual theme: $theme_key.";
   if ($inherited) {
     $output .= ' Theme negotiation inheritance is being tested.';
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php
index e51b1e1..9d01d9a 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/cache/CachePluginBase.php
@@ -315,7 +315,7 @@ public function generateOutputKey() {
         'result' => $this->view->result,
         'roles' => $user->getRoles(),
         'super-user' => $user->id() == 1, // special caching for super user.
-        'theme' => $GLOBALS['theme'],
+        'theme' => \Drupal::themeNegotiator()->getActiveTheme(),
         'langcode' => language(Language::TYPE_INTERFACE)->id,
         'base_url' => $GLOBALS['base_url'],
       );
