Active Context Reporter

I want to be able to get a live preview of certain global context data: context.area.type, context.mode, etc.

Handlers seem to only work for Scene properties, not Context changes.

I figured this means running a modal operator, but whenever I try this it seems to be ‘stuck’ in whatever context it was called from - e.g. Text Editor, and it doesn’t update the context with mouse events. When I tried to change the context to window or screen I got the same result (but possibly user error on my part).

Basically, I want a handler updates when the Status Bar updates, whenever the mouse moves into a new global context.

I tried with the depsgraph, but couldn’t get what I was looking for.

Is this possible?

Not sure if what I wrote above makes sense to everybody, so I wrote an operator that returns the info that I need, and whenever I call it manually (creating a quick keybind in Preferences) it works, but whenever I try to call it from a modal operator, or a timer, it seems to be stuck in the context it’s called from.

Here’s the operator that prints the context info:

import bpy


def main(context):
    area = context.area.type
    ui_type = context.area.ui_type
    region = context.region.type
    
    mode = context.mode
    
    scene = context.scene.name
    view_layer = context.view_layer.name
    workspace = context.workspace.name
    
    if area == ui_type:
        context_items = [scene, view_layer, workspace, area, region, mode]
    else:
        context_items = [scene, view_layer, workspace, ui_type, area, region, mode]

    context_items = [item.title() for item in context_items]
    
    return context_items


class ContextReporter(bpy.types.Operator):
    """Prints the current context to the system console"""
    bl_idname = "window.context_reporter"
    bl_label = "Context Reporter"

    def execute(self, context):     
        for item in main(context):
            print(item)
        return {'FINISHED'}


def menu_func(self, context):
    self.layout.operator(ContextReporter.bl_idname, text=ContextReporter.bl_label)


def register():
    bpy.utils.register_class(ContextReporter)
    bpy.types.VIEW3D_MT_object.append(menu_func)


def unregister():
    bpy.utils.unregister_class(ContextReporter)
    bpy.types.VIEW3D_MT_object.remove(menu_func)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.window.context_reporter()

Thanks for any pointers anyone can provide!