Index: modules/taxonomy.views.inc
===================================================================
--- modules/taxonomy.views.inc	(revision 1454)
+++ modules/taxonomy.views.inc	(working copy)
@@ -308,6 +308,9 @@
       'handler' => 'views_handler_argument_term_node_tid_depth',
       'accept depth modifier' => TRUE,
     ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_term_node_tid_depth',
+    ),
   );
 
   $data['node']['term_node_tid_depth_modifier'] = array(
@@ -357,6 +360,9 @@
       'views_handler_filter_term_node_tid' => array(
         'parent' => 'views_handler_filter_many_to_one',
       ),
+      'views_handler_filter_term_node_tid_depth' => array(
+        'parent' => 'views_handler_filter_term_node_tid',
+      ),
     ),
   );
 }
Index: modules/taxonomy/views_handler_filter_term_node_tid_depth.inc
===================================================================
--- modules/taxonomy/views_handler_filter_term_node_tid_depth.inc	(revision 0)
+++ modules/taxonomy/views_handler_filter_term_node_tid_depth.inc	(revision 0)
@@ -0,0 +1,72 @@
+<?php
+// $Id: $
+/**
+ * Filter handler for taxonomy terms with depth.
+ *
+ * This handler is actually part of the node table and has some restrictions,
+ * because it uses a subquery to find nodes with
+ */
+class views_handler_filter_term_node_tid_depth extends views_handler_filter_term_node_tid {
+  function operator_options() {
+    return array(
+      'or' => t('Is one of'),
+    );
+  }
+  
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['depth'] = array('default' => 0);
+
+    return $options;
+  }
+  
+  function extra_options_form(&$form, &$form_state) {
+    parent::extra_options_form($form, $form_state);
+
+    $form['depth'] = array(
+      '#type' => 'weight',
+      '#title' => t('Depth'),
+      '#default_value' => $this->options['depth'],
+      '#description' => t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'),
+    );
+  }
+  
+  function query() {
+    $this->ensure_my_table();
+    
+    if (count($this->value) == 0) {
+      return;
+    } else if (count($this->value) == 1) {
+      $placeholder = " = %d";
+    } else {
+      $placeholder = " IN (" . implode(', ', array_fill(0, sizeof($this->value), '%d')) . ")";
+    }
+    
+    $subquery = "\n  SELECT tn.vid FROM {term_node} tn\n";
+    $where = "  WHERE tn.tid $placeholder\n";
+    $args = $this->value;
+    $last = "tn";
+
+    if ($this->options['depth'] > 0) {
+      $subquery .= "    LEFT JOIN {term_hierarchy} th ON th.tid = tn.tid\n";
+      $last = "th";
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery .= "    LEFT JOIN {term_hierarchy} th$count ON $last.parent = th$count.tid\n";
+        $where .= "    OR th$count.tid $placeholder\n";
+        $args = array_merge($args, $this->value);
+        $last = "th$count";
+      }
+    }
+    else if ($this->options['depth'] < 0) {
+      foreach (range(1, abs($this->options['depth'])) as $count) {
+        $subquery .= "    LEFT JOIN {term_hierarchy} th$count ON $last.tid = th$count.parent\n";
+        $where .= "    OR th$count.tid $placeholder\n";
+        $args = array_merge($args, $this->value);
+        $last = "th$count";
+      }
+    }
+    
+    $this->query->add_where(0, "$this->table_alias.$this->real_field IN ($subquery$where  )", $args);
+  }
+}
