What context should be passed to screen.area_move() to make it work? It seems it's possible to use screen.area_move because it is accomplished in the Pie Menu Editor addon and there's a thread on blenderartists.org where the author demonstrates using an operator from his addon to run screen.area_move. I'm wondering, how did he accomplish this?

#Just quickly converting the example code from the thread
C = bpy.context
a = C.area
x = a.x + (a.width &gt;&gt; 1)
y = a.y + a.height
C.window.cursor_warp(x, y)

#Replace Pie Menu Editor timeout operator (which I don't have access to) with timer app handler.
#bpy.ops.pme.timeout(delay=0.0001, cmd="bpy.ops.screen.area_move(x=%d, y=%d, delta=-100)" % (x, y))

def move_area():
    bpy.ops.screen.area_move(x=x, y=y, delta=-100)

bpy.app.timers.register(move_area, first_interval=1)


I've tried emulating the code posted on the thread and substituted his timeout operator with a timer apphandler. The apphandler works, but the context is still not correct. Also no combination (that I've tried) of override context passed seems to work.

Examining Blender source screen_ops.c the only poll for the operator SCREEN_OT_area_move seems to be for the position of the cursor:

ot-&gt;poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */


Which I've managed to provide but still doesn't seem to be enough. Anyone ever get this particular operator working, or in any way figure out how to programmatically change the x, y, width or height of an editor?
Timer threads have little sense of context.

As outlined here

Context is incorrect when calling from a timer

need to pass some context to the timer.  In this case I've passed a copy of the text editor context when hitting the button.  Pretty sure just the screen is required context, or at most the window and screen.



Note found that calling the resize operator with no delta and moving the mouse worked from within a timer, however it is STICKY and a mouse click (or other events) are needed to unstick the mouse from moving the area.  Not sure how to release.  It is actually quite a handy way to resize the panels.. but still not quite right

import time, bpy, functools
from bpy import context

def snooper(c, w, a, x, y, delta, poll_retries=500):
    #bpy.ops.wm.redraw_timer(c, time_limit=0, iterations=10)

    while not bpy.ops.screen.area_move.poll(c, 'INVOKE_REGION_WIN'):
        poll_retries -= 1
        if not poll_retries:
            return None # out of retries

    # should poll now
    bpy.ops.screen.area_move(c,'INVOKE_REGION_WIN', x=x, y=y)

    y += delta
    w.cursor_warp(x, y)
    return None


if __name__ == '__main__':

    context = bpy.context
    a = context.area
    w = context.window
    x = a.x + (a.width &gt;&gt; 1)
    y = a.y + a.height     

    w.cursor_warp(x, y)
    bpy.app.timers.register(functools.partial(snooper, context.copy(), w, a, x, y, delta=100), first_interval=0.2)


Scissor sets



Looked into the screen areas a while back re overriding context.  Recommend matching areas by the midpoints of edges and if both edge lengths also match they can be "pseudo joined"  into a new area until we have one full window area with instructions on how to split back.  Not unlike a binary tree.

Doing something similar here would be the go, giving the option of 1 to 4 possible resizes..  by looking for any "pseudo joined" areas in tree that have context.area and another area from the screen areas collection.