Minecraft Inventory Management
C++, 498 482 457 bytes
If this function is just called once, it can be 455 bytes.
I found that almost every online GCC compilers (including TIO) forbids me to omit the type of the function f. However, the GCC on my computer allows that, and I don't know why.
This one can handle large inputs if a slot can contain that number of items (though needs a larger array and will probably run out of time).
#import&lt;bits/stdc++.h&gt;
#define t N.first
#define X n.erase(n.find
#define p(c){if(c==r)return l;if(L.emplace(w={n,c},l).second)Q[U++]=w;}
#define T(S,C)n.insert(S);p(C)X(S));
using m=std::multiset&lt;int&gt;;using s=std::pair&lt;m,int&gt;;s Q[99999];int x,l,B,U;int f(int a,int r){if(!r)return 0;std::map&lt;s,int&gt;L;s f({a},B=0),w,N;L[Q[U=1]=f];for(;;){l=L[N=Q[B++]]+1;x=N.second;t.insert(0);for(int i:t){m n=t;X(i));if(x){T(i+x,0)T(i+1,x-1)}if(!x&amp;&amp;i){p(i)T(i/2,i-i/2)}}}}

Ungolfed:
#include &lt;map&gt;
#include &lt;set&gt;
#include &lt;queue&gt;
#include &lt;iostream&gt;

using namespace std;

struct state {
    multiset&lt;int&gt; t; int q;
    bool operator&lt;(const state&amp; i) const { return make_pair(t, q) &lt; make_pair(i.t, i.q); }
};

int f(int a, int target) {
    if (target == 0) return 0;

    map&lt;state, int&gt; len;
    queue&lt;state&gt; qu;
    state first = {{a}, 0};
    qu.push(first);
    len[first] = 0;

    #define push(c) { state a = {n, c}; auto t = len.insert({a, l + 1}); if (t.second) { \
        if (a.q == target) return l + 1; qu.push(a); \
    } } // push new state into queue and check for termination
    #define next(stk, cur) { n.insert(stk); push(cur); n.erase(n.find(stk)); }
    // insert new stack, push new state, erase the stack (for another use)

    while (qu.size()) { // BFS cycle
        state now = qu.front();
        qu.pop();

        int q = now.q;
        int l = len[now];

        multiset&lt;int&gt; n(now.t);
        for (int i : now.t) { // click on non-empty stack
            n.erase(n.find(i));
            if (!q) { // nothing on cursor
                push(i); // click left
                next(i / 2, (i + 1) / 2); // click right
            }
            else { // item on cursor
                next(i + q, 0); // click left
                next(i + 1, q - 1); // click right
            }
            n.insert(i);
        }
        if (q) { // click on empty stack
            next(q, 0); // click left
            next(1, q - 1); // click right
        }
    }
}