Index: skinr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.module,v
retrieving revision 1.40
diff -u -p -r1.40 skinr.module
--- skinr.module	15 Jan 2011 20:32:27 -0000	1.40
+++ skinr.module	16 Jan 2011 01:04:05 -0000
@@ -495,8 +495,24 @@ function skinr_implements() {
     // implementations of all enabled themes, the equivalent of the module hook
     // is a theme .info file property 'skinr' that has the sub-keys 'api' and
     // optionally 'directory' defined.
-    foreach (list_themes() as $name => $theme) {
-      if (!empty($theme->status) && isset($theme->info['skinr']['api']) && $theme->info['skinr']['api'] == SKINR_VERSION) {
+    // Account for all enabled themes and (any recursive) base themes of them,
+    // regardless of whether base themes are enabled.
+    $all_themes = list_themes();
+    $themes = array();
+    foreach ($all_themes as $name => $theme) {
+      // If the theme is enabled, add it to the stack.
+      if (!empty($theme->status)) {
+        $themes[$name] = $theme;
+        // Find and add all base themes of the enabled theme to the stack.
+        // @see drupal_theme_initialize()
+        while ($name && isset($all_themes[$name]->base_theme)) {
+          $name = $all_themes[$name]->base_theme;
+          $themes[$name] = $all_themes[$name];
+        }
+      }
+    }
+    foreach ($themes as $name => $theme) {
+      if (isset($theme->info['skinr']['api']) && $theme->info['skinr']['api'] == SKINR_VERSION) {
         // Ensure that the theme name and the extension type is registered.
         $cache[$name] = array(
           'type' => 'theme',
Index: tests/skinr.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/tests/skinr.test,v
retrieving revision 1.8
diff -u -p -r1.8 skinr.test
--- tests/skinr.test	15 Jan 2011 20:32:27 -0000	1.8
+++ tests/skinr.test	16 Jan 2011 01:13:38 -0000
@@ -98,6 +98,8 @@ class SkinrApiTestCase extends DrupalWeb
 
   function setUp() {
     parent::setUp(array('skinr', 'skinr_test', 'skinr_test_incompatible'));
+    // Enable skinr_test_subtheme, but NOT the basetheme.
+    theme_enable(array('skinr_test_subtheme'));
   }
 
   /**
@@ -120,6 +122,16 @@ class SkinrApiTestCase extends DrupalWeb
       'skinr_test' => array(
         'directory' => 'skins',
       ),
+      'skinr_test_basetheme' => array(
+        'type' => 'theme',
+        'api' => 2,
+        'directory' => 'skins',
+      ),
+      'skinr_test_subtheme' => array(
+        'type' => 'theme',
+        'api' => 2,
+        'directory' => 'skins',
+      ),
     );
     foreach ($all_expected as $name => $expected) {
       // Populate defaults.
@@ -170,6 +182,14 @@ class SkinrApiTestCase extends DrupalWeb
     )));
     unset($skin_info['skinr_test_example']);
 
+    // skinr_test_basetheme is registered via hook_skinr_skin_info() in
+    // skinr_test_basetheme.skinr.inc.
+    $this->assertTrue(isset($skin_info['skinr_test_basetheme']), 'Skin registered in $basetheme.skinr.inc found.');
+    $this->assertEqual($skin_info['skinr_test_basetheme']['source']['path'], $path . '/tests/themes/skinr_test_basetheme', t('Skin path points to basetheme directory: @path', array(
+      '@path' => $skin_info['skinr_test_basetheme']['source']['path'],
+    )));
+    unset($skin_info['skinr_test_basetheme']);
+
     // Ensure that skinr_test_incompatible is not contained.
     $this->assertTrue(!isset($skin_info['skinr_test_incompatible']), 'Incompatible skin not found.');
     // After asserting all expected, the list of skins should be empty.
Index: tests/skinr_test.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/tests/skinr_test.module,v
retrieving revision 1.2
diff -u -p -r1.2 skinr_test.module
--- tests/skinr_test.module	11 Jan 2011 00:53:15 -0000	1.2
+++ tests/skinr_test.module	16 Jan 2011 00:54:29 -0000
@@ -9,3 +9,17 @@
  * into a conditionally loaded $module.skinr.inc file, so this .module file
  * only exists, because Drupal requires a .module file to exist.
  */
+
+/**
+ * Implements hook_system_theme_info().
+ *
+ * @see http://drupal.org/node/953336
+ */
+function skinr_test_system_theme_info() {
+  $path = drupal_get_path('module', 'skinr_test');
+  $test_themes = array('basetheme', 'subtheme', 'basetheme_other', 'subtheme_other');
+  foreach ($test_themes as $theme) {
+    $themes["skinr_test_{$theme}"] = $path . "/themes/skinr_test_{$theme}/skinr_test_{$theme}.info";
+  }
+  return $themes;
+}
Index: tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc
===================================================================
RCS file: tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc
diff -N tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/themes/skinr_test_basetheme/skinr_test_basetheme.skinr.inc	15 Jan 2011 21:48:02 -0000
@@ -0,0 +1,13 @@
+<?php
+// $Id$
+
+/**
+ * Implements hook_skinr_skin_info().
+ */
+function skinr_test_basetheme_skinr_skin_info() {
+  $skins['skinr_test_basetheme'] = array(
+    'title' => 'Base theme skin',
+    'default_status' => 1,
+  );
+  return $skins;
+}
