Hi, > Well, I used to like that behaviour of "typewriter capslock" (with shift > key removing the caps lock, and the capslock affecting all keys and > being a shift lock in fact)
Unfortunately I can't imagine how to make such mode ("affects all keys" but "Shift cancels Caps" ) in XKB. > I tested it and it seems to work correctly with caps:shift > (setxkbdmap "fr" -options "caps:shift") ? Yes, it works! And it's a big surprise to me. Of course now I understand why it happens but I didn't guess until you wrote about it. :-) Let me explain. 1) Xlib converts a keycode to a keysym in two steps. At the first step it chooses a cell in a keyboard map table according to the state of modifiers and gets a keysym. And the second step is that if Lock modifier is set Xlib tries to convert the keysym to uppercase one using an internal table. 2) For the cell choosing it uses rules called 'key type'. Such rule describes what modifiers should be taken in account and what combiantion of modifiers match each shift level. (Note that the modifers can be not Shift only but also Control, Alt, etc.). Each key can have own type (refer to own rule) and if there are more than one 'xkb group' in a keybaord map the key can have different types for different groups. 3) The first step subroutine can remove some modifiers ('consume' in XKB terms) if they are used for the sell selection. Otherwise it would be imposible to cancel temporary a Lock modifier action. Thus if we want the "Shift cancels Caps" mode we have to specify in the type description that if Shift is pressed, Lock modifier should be removed (or hidden) and the second step will leave the keysym unchaged. 4) xkbcomp program itself tries recognize what key is alphabetic and what key is not and assign them different types (rules). The algorithm is simple, if the keysym in the first level is some lowercase letter and the keysym in the second level is some uppercase one it is an alphabetic key (note: the program doesn't check any matching between them). Otherwise xkbcomp thinks it is a 'non-alphabetic key with two levels'. Also one can explicitly specify the key type in a keyboard map. Now we can understand the results of your experiments. The key [ccedilla 9] was not recognized as an alphabetic key because the second symbol isn't an uppercase letter. On the other hand the rule for 'simple two level' keys is: if Shift is set choose the second level, otherwise choose the first one. But (what I didn't guess) the rule says nothing about the consuming of Lock modifier. And if Lock is set the second step converts ccedilla to uppercase Ccedilla. If Shift is also set the first step chooses '9' and the second step does nothing. Actually there is not a difference between the 'two level' type and the 'alphabetic' type in caps:internal mode except Lock+Shift case. 'Alphabetic-internal' rule chooses first level when there is not any modifiers set and the second level when Shift is active. If Lock (without Shift) is set it chooses the first level keysym but allow second step to make it uppercase one (using internal table !). But the case Lock+Shift is processed differently. 'Two level' rule chooses the second level symbol but 'alphabetic-internal' rule still gets the first level keysym but consume Lock modifiers and prevents the capitalization at the secont step. Thus you see that the 'alphabetic-internal' rule *never* chooses the second level if Lock is set but only pass it to or hide it from the second step. The rule 'alphabetic' in caps:shift mode differ from both mentioned rules. It *always* consume Lock and leave the second step idle. On the other hand it use Lock for choosing the second level and returns to the first level when Shift is added to Lock. > > > And what is exactly the difference between the caps:shift and the currently > > > default behaviour? > > > > In "caps:shift mode" if Lock modifier is set Xlib gets from keyboard map > > a keysym from the second shift level the same as is chosen when Shift modifier > > is set. > > ?? You said that such behaviour is no more present. No, I said that CapsLock key doesn't control Shift modifier (saying 'modifiers' I don't mean keys themselvs but bit flags that the keys set). The CapsLock key always set Lock modifier. But in this mode Lock and Shift modifiers (flags) cause the same action at a level choosing. > > But since CapsLock key doesn't lock Shift modifier but Lock modifier > > it allows to distinguish cases "CapsLock is active" and "CapsLock is active and > > Shift key is pressed". Also it allows only part of keys (alphabetical ones) > > be affected by CapsLock. > > So, it is not the second shift level that is chosen; but > - if the second shift level is alphabetic, it is chosen; > - if not, the first shift level is uppercased. > > is that right? Not exactly, but it looks like that. :-) As I tried to explain above, "if the second shift level is alphabetic" (and uppercase) the 'alphabetic' rule is applied and in caps:shift mode it means that the second level is chosen. But "if not" it is a key of 'simple two level' type and it means that Lock is not taken in account at the step (level choosing) but causes a case convertion (internal) at the second step. > In such case, trhe difference between caps:shift and caps:internal > will only be visible in keyboard layouts with alphabetic letters on > unshifted and shifted positions of a same key, but which are not different > cases of the same letters (that is the case of the Swiss keyboard, I'll > test with de_CH... Yes. > The case of "i" with and without dots work well; some more tests show this: > - when i/Iabovedot are paired in a same key, Iabovedot is used as the uppercase > of "i". Otherwise, "I" is used as the upepercase. Yes. If the second level keysym was not an uppercase letter the key was recognized as non-alphabetic and 'i' was converted according to internal table. > - when "idotless" is paired with "I", then "I" is used as the uppercase; > otherwise CapsLock has no effect on that letter and the lowercase > "idotless" is returned. Probably ConvertCase procedure doesn't know how to convert it to uppercase. > In fact the behaviour (with caps:internal or caps:shift, I see no difference > at all) seems to be this one (when capslock is active): > > - if position shift 1 is a lowercase letter, and if shift2 is an uppercase > letter; then the symbol in position shift2 is used as the uppercase value, > and the symbol in shift1 as the lowercase value. > that is, pressing the key gives the uppercase. pressing shift-key gives > the lowercase (the letters may be different, eg: [ x, A ] will > work. Right. As I said xkbcomp just wants the first symbol be lowercase and the second one be uppercase to consider the key as alphabetic. > - otherwise, for each alphabetic letter, the uppercase letter is returned; > also for symbols in shift2 (eg: [ x, a ] gives "X" when you press > the key, and "A" when pressed with shift). It's understandable too. Suck keys are processed as 'two level non-alphabetic' it means that Shift chooses the level and Lock causes a case-convertion at the second step. Since the 'alphabetic' rule isn't used there it doesn't matter what mode it has. Anyway the 'internal case-conversion' happens. > - for non alphabetic letters, the symbol is returned as (CapsLock has > no effect) Yes. The rule in this case is 'two level'. Shift modifier chooses level. Lock does nothing. > So it seems the problem is indeed solved; but the behaviour (a quite good > one in fact) is different of what you and I thought it was. Yes. Thank you for your experiments. I wrote a test program that prints keysyms for all keys in a map for all combinations of Lock and Shift. And than I ran it for all layouts in both modes and compared the results. There are few differences (in 'tr' for example) and in all cases caps:shift produces more reasonable result. There is one only exeption in 'ca' and 'ca_enhanced' maps: the key [ eth, Dstroke ]. It's recognized as alphabetical one (lowercase - uppercase letters) and the results are different. Lock with caps:internal gives ETH but with caps:shift it gives Dstroke (and there is not way to get ETH). But it can be fixed easy in the map. We just have to specify explicitly that the key must be 'two level' but not 'alphabetic'. Also there is a problem with new 'one group' keymaps that appeared in 4.3.0. In such keymap there are many four-level keys. The problem is that third and fourth levels in some cases is an alphabetic pair but in some other is not, therefore they should be processed differently for different kinds of four-level keys. But I made only one 'alphabetic' rule for all such keys and too simplified procedure for recognizing them as alphabetic (it checks only two first levels and ignores others). Now I see that I have to improve such keys processing. But when it be done I think we can make caps:shift mode the default. -- Ivan U. Pascal | e-mail: [EMAIL PROTECTED] Administrator of | Tomsk State University University Network | Tomsk, Russia _______________________________________________ Devel mailing list [EMAIL PROTECTED] http://XFree86.Org/mailman/listinfo/devel