O sistema de Ctrl+Z era muito simples, igual ao do Photoshop que só tem como voltar a ação uma vez. No seu caso, basicamente no exato momento que terminar uma edição na surface você tem que verificar se a sprite usada como cópia de segurança existe e deletá-la para liberar espaço na memória e recriá-la novamente a partir da surface já modificada.
Eu não sei como faz para saber se o app está em foco ou não, pois eu não desenvolvo para dispositivos móveis, mas pelo que eu li na documentação as surfaces são armazenadas na memória de texturas e por isso podem ser destruídas quando a aplicação é minimizada ou perder o foco, mas não quer dizer que elas sempre serão destruídas, só em caso do sistema necessitar de mais memória para outras tarefas ele vai apagar as surfaces para liberar espaço. Então acho que seria melhor apenas verificar se a surface existe ou não usando a função
surface_exists(), a própria documentação do GM:s alerta para em caso de usar ou modificar uma surface, sempre fazer a verificação se a surface existe para evitar erros
Docs: Surfaces. Então caso a surface "não" exista, você precisa criá-la novamente e desenhar a sprite usada como cópia de segurança.
Se você querer fazer o sistema de Ctrl+Z, então "antes" ou quando você "começar" a edição da surface já tem que salvar a surface sem a alteração em uma sprite secundária, para caso a função de "undo" seja usada você pintar essa sprite novamente na surface para anular a modificação.