Second try: 😉
pre_get_posts runs AFTER parse_query(). parse_query() transforms ‘meta_key’ etc. into ‘meta_query’. get_posts() doesn’t seem to react on ‘meta_key’ etc. directly. So try adding $query->parse_query() after your $query->set() calls or use filter that runs before parse_query (edited, the parse_query() filter doesn’t work, either – it runs too late).
Edit: to do the switch:
function my_timeswitch() {
$operators = array(
'>=' => 'future',
'<=' => 'past'
);
?>
<select name="meta_compare">
<?php
foreach ($operators as $k => $v) {
printf( "<option %s value="%s">%s</option>\n", selected($_GET['meta_compare'], $k, false), esc_attr($k), __($v));
}
?>
</select>
<?php
}
add_action('restrict_manage_posts', 'my_timeswitch');
This may work just on it’s own. If not, you’ll have to change the name to something else, then register a new public query variable via the query_vars filter and then react on it via the parse_query filter.