EVENT_MOUSEDOWN mods = 0 on canvas first click

Archives Forums/BlitzMax Bug Reports/EVENT_MOUSEDOWN mods = 0 on canvas first click

skn3(Posted 2010) [#1]
When you deactivate a canvas and then click to activate it, it will produce the event_mousedown but any modifiers that are being held are not recorded in the event.

I am testing this on mac I dunno about windows.


SebHoll(Posted 2010) [#2]
This seems to be in fact a BRL.System bug, as it happens with Max2D contexts too. The problem is that the modifiers aren't updated if the application isn't a first-responder when the key state changes. To fix, replace the first half of the bbSystemEmitOsEvent() function (in BlitzMax/mod/brl.mod/system.mod/system.macos.m) with:

void bbSystemEmitOSEvent( NSEvent *event,NSView *view,BBObject *source ){
	int inView;
	NSEventType type;
	NSString *characters;
	int ev=0,data=0,x=0,y=0,oldMods=mods,mask;
	float f;
	
	mods=[event modifierFlags];
	
	type=[event type];

	switch( type ){
	case NSKeyDown:
		if( data=bbSystemTranslateKey( [event keyCode] ) ){
			ev=[event isARepeat] ? BBEVENT_KEYREPEAT : BBEVENT_KEYDOWN;
			bbSystemEmitEvent( ev,source,data,bbSystemTranslateMods(mods),0,0,&bbNullObject );
		}
		characters=[event characters];
		if( [characters length]!=1 ) return;
		data=[characters characterAtIndex:0];
		if( data>=0xf700 && data<=0xf8ff ) return;
		ev=BBEVENT_KEYCHAR;
		data=bbSystemTranslateChar( data );
		break;
	case NSKeyUp:
		data=bbSystemTranslateKey( [event keyCode] );
		if( !data ) return;
		ev=BBEVENT_KEYUP;
		break;
	case NSFlagsChanged:
		deltaMods=mods^oldMods;
		if( deltaMods & (mask=LSHIFTMASK) ) data=KEY_LSHIFT;
		else if( deltaMods & (mask=RSHIFTMASK) ) data=KEY_RSHIFT;
		else if( deltaMods & (mask=LCTRLMASK) ) data=KEY_LCONTROL;
		else if( deltaMods & (mask=RCTRLMASK) ) data=KEY_RCONTROL;
		else if( deltaMods & (mask=LALTMASK) ) data=KEY_LALT;
		else if( deltaMods & (mask=RALTMASK) ) data=KEY_RALT;
		else if( deltaMods & (mask=LSYSMASK) ) data=KEY_LSYS;
		else if( deltaMods & (mask=RSYSMASK) ) data=KEY_RSYS;
		if( !data ) return;
		ev=(mods & mask) ? BBEVENT_KEYDOWN : BBEVENT_KEYUP;
		break;
This changes behaviour so that modifiers are updated after every system event. A bit of a sledge-hammer to crack a walnut approach, but it works. :-)