When you use a window join, your join function will be applied for each match of the tuple (IN1_key, IN2_key). If there's no match (i.e. there are no elements IN1_key matching IN2_key), elements will not be emitted to your join function.
However, the input for Cogroup is an iterable of IN_key1 and IN_key2, where each one of the iterables may be empty. This means that if IN1_key exists, but no matching IN2_key, the Cogroup function will still be invoked with an empty iterable for IN2_key. This generalization allows you to implement outer join semantics as well.