The constraint is just a list. This list can be constructed (in Python) using advanced rules, like pick out all the atoms of a particular elements, and so on.
It depends on the situation, whether it's more convenient to click each one or use rules. If the atoms you want to fixate are "random" in the sense that it's an atom here and another atom over there, then clicking is easier since you get a visual feedback on which atoms you actually picked.
But if it's more straightforward, then simple Python constructs is very powerful. For example, I had a carbon nanotube with a Stone-Wales defect and wanted to optimize it (as bulk) while constraining all the "outer" atom, which were the first and last 40 atoms out of the total 160 carbons. So, I did
bulk_configuration = OptimizeGeometry(
bulk_configuration,
maximum_forces=0.05*eV/Ang,
constraints=range(40)+range(120,160),
trajectory_filename='sw_defect.nc',
)