Constraints

JCN releases himself from handcuffsWhen a window changes position or size, there are rules of thumb about how it should happen.  The trouble is that sometimes in real life these rules of thumb are contradictory, and we need a way to decide between them.  This all used to be done in an ad-hoc way, but in 2005 Elijah swooped in and made one much more elegant system out of the chaos.  In this system, every rule of thumb is represented by a constraint. There are currently nine of these, and going from most to least important they are:

  • constrain_partially_onscreen: “Some part of every window must appear on the screen.”
  • constrain_titlebar_visible: “Generally, some part of every window’s titlebar should always appear on the screen.”
  • constrain_size_limits: “If the application has requested that its window should not grow bigger or smaller than some size, we should honour that.”
  • constrain_fullscreen: “A fullscreen window should take up the entire xinerama area.”
  • constrain_maximization: “A maximised window should take up the full screen.”
  • constrain_size_increments: “If the application has requested that its window’s size should only be a multiple of some number, we should honour that.”
  • constrain_fully_onscreen: “It’s nice if the whole of the window appears on the screen at once.” (This rule doesn’t apply if it’s you, the user, moving the window about; you’re presumed to know where you want the window.)
  • constrain_to_single_xinerama: “It’s nice if a window appears on a single xinerama monitor.”
  • constrain_aspect_ratio: “If the application asks to have a window of a particular aspect ratio (say, square, or φ), it’s nice if we honour that.”

Every one of these constraints is represented by a C function which takes arguments of the window in question, a flag to say whether it’s allowed to modify the window, and some other things.  The return result is ignored if the function wasn’t allowed to modify the window.  But in read-only mode, it must return false only if it could never be satisfied with the window as it is.  If it returns true, the function either thinks the window is all right as it is, or believes itself capable of changing the window until it’s satisfactory.

In order to enforce constraints, first of all we call all the constraint functions, permitting them to make changes, and ignoring whether they say they were satisfied.  Then when they’re done, we call them all again in read-only mode; if any of them tells us it can’t be satisfied, then clearly there’s an inconsistent set of things we’re wanting here.  (Perhaps we should also have a constraint called constraint_i_want_a_pony.)  So we go round again, but we lower our expectations a little by taking away a group of the least important constraints, to see whether that helps us gain unanimity.  If not, we go round again with the next most trivial group removed, and so on.

If you want to know more, you should read Elijah’s overview of constraints and then consider diving into the code.  Some current bugs concern constraints, so it would be good for people to try to get their heads around them.

Photo credit: Amit Gupta, cc-by-nc.