Page MenuHome

Wrong value for bpy.context.area.spaces.active in modal Operator
Closed, InvalidPublicTO DO

Description

Wrong value for bpy.context.area.spaces.active in modal Operator

--- Operating System, Graphics card ---
MaxOSX 10.8.4

renderer: 'NVIDIA GeForce GT 650M OpenGL Engine'
vendor: 'NVIDIA Corporation'
version: '2.1 NVIDIA-8.12.47 310.40.00.05f01'

Full system description in a text bugger of the attached scene.


--- Blender version with error, and version that worked ---
Reproduced in both 2.66a and 2.68a


--- Short description of error ---
I just found a buggy/weird behaviour in writing a modal Operator.
I'm writing a modal Operator invoked through a timed callback.
My aim is to retrieve in real-time the 3DView currently activated by the user. It means retrieving the area that is currently under the mouse pointer.

The operator can be activated from any area using the alt+shift+C shortcut.

There is a problem in the modal execution.
Even if the user moves the mouse across the screen, the Space instance returned by bpy.context.area.spaces.active is always the same! The one active at the moment of the shortcut stroke.

At beginning I thought it was a desired behaviour: maybe the context is "frozen" at the moment of first invocation.
But a couple of hints suggested me the contrary:
- The list of "selected_objects" is correctly updated
- If I switch to another screen (e.g., from Scripting to Default), while the operator is active, everything starts to behave correctly!


--- Steps for others to reproduce the error (preferably based on attached .blend file) ---
HOW TO REPRODUCE THE BUG:
- File -> New
- Switch to Scripting screen
- Paste the provided script into a new text area
- Run it
- Move the mouse in an area not "grabbing" the keytypes, like the 3D View or the Properties
- Press shift+alt+c
- The console will print every 2 secs the active space
- Regardless of mouse movements, the active space will remain the one active at the moment of shortcut press
- Object selection is printed correctly
- Switch to a different screen (e.g. Default or Animation)
- The active space will be correctly identified
- Switch back to Scripting
- The active space will be AGAIN WRONGLY identified

Event Timeline

It is an intentional feature, modal operators are executed in the screen/area/region context they were originally started in. If you change the screen that's not possible anymore of course, so at that point the context is lost. Builtin modal operators in Blender like transform do not allow you to switch screen anyway, and they are intended to keep affecting the original area if you move your mouse outside of it.

The other reason it works this way is because it means you can for example click Translate in the toolbar but the context of the operator will be set to the main 3D view region instead of the toolbar region.

You're implementing a very different kind of operator ('modal' means it blocks other interaction until done). Maybe there should be some way to control this context freezing.

Feature!?
Ouch! I don't like this behaviour.
The semantic of the word "active" in bpy.context.area.spaces.active should be preserved.
Any command might anyway store the target space at the moment of invokation and use it later.
Or, to address the toolbar/3DView issue you mentioned, I would rather introduce a bpy.context.area.spaces.target attribute.

Anyway, this is a big issue for my development.

But, as you pointed out, I'm misusing the concept of modal Operator.
My aim is to create a background support for an input device that, when "moved", has to control the selected object using the transform of the currently active 3D View.
So what would be a better place to register a timed callback? A handler of the Screen? Any suggestion?

best,
FN

Assigning to Campbell, to see what he thinks about this.

Probably the best option is to add an operator flag for this. I'm not sure what to call it. 'NO_PRESERVE_CONTEXT', 'DECOUPLE_CONTEXT', 'CONTEXT_FOLLOWS_CURSOR', .. not really happy with any of them.


By the way, bpy.context.area.spaces.active means that you get the active space in the context area, not the active area.

Set as TODO: http://wiki.blender.org/index.php/Dev:2.5/Source/Development/Todo/UserInterface#Events

Campbell Barton (campbellbarton) changed the task status from Unknown Status to Unknown Status.Sep 25 2013, 12:55 PM