Allow removing background image via @ set-background-image

This commit is contained in:
Kovid Goyal 2020-02-02 20:41:52 +05:30
parent 75c47a8659
commit 01b11b8a53
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 41 additions and 26 deletions

View File

@ -1260,7 +1260,9 @@ def set_background_opacity(boss, window, payload):
# set_background_image {{{
@cmd(
'Set the background_image',
'Set the background image for the specified OS windows.',
'Set the background image for the specified OS windows. You must specify the path to a PNG image that'
' will be used as the background. If you specify the special value "none" then any existing image will'
' be removed.',
options_spec='''\
--all -a
type=bool-set
@ -1286,7 +1288,8 @@ How the image should be displayed. The value of configured will use the configur
)
def cmd_set_background_image(global_opts, opts, args):
'''
data+: Chunk of at most 512 bytes of PNG data, base64 encoded. Must send an empty chunk to indicate end of image.
data+: Chunk of at most 512 bytes of PNG data, base64 encoded. Must send an empty chunk to indicate end of image. \
Or the special value - to indicate image must be removed.
img_id+: Unique uuid (as string) used for chunking
match: Window to change opacity in
layout: The image layout
@ -1300,6 +1303,9 @@ def cmd_set_background_image(global_opts, opts, args):
raise SystemExit('Must specify path to PNG image')
path = args[0]
ret = {'match': opts.match, 'configured': opts.configured, 'layout': opts.layout, 'all': opts.all, 'img_id': str(uuid4())}
if path.lower() == 'none':
ret['data'] = '-'
return ret
if imghdr.what(path) != 'png':
raise SystemExit('{} is not a PNG image'.format(path))
@ -1321,25 +1327,31 @@ def set_background_image(boss, window, payload):
import tempfile
pg = cmd_set_background_image.payload_get
data = pg(payload, 'data')
img_id = pg(payload, 'img_id')
if img_id != set_background_image.current_img_id:
set_background_image.current_img_id = img_id
set_background_image.current_file_obj = tempfile.NamedTemporaryFile()
if data:
set_background_image.current_file_obj.write(standard_b64decode(data))
return no_response
if data != '-':
img_id = pg(payload, 'img_id')
if img_id != set_background_image.current_img_id:
set_background_image.current_img_id = img_id
set_background_image.current_file_obj = tempfile.NamedTemporaryFile()
if data:
set_background_image.current_file_obj.write(standard_b64decode(data))
return no_response
f = set_background_image.current_file_obj
set_background_image.current_file_obj = None
f.flush()
windows = windows_for_payload(boss, window, payload)
os_windows = tuple({w.os_window_id for w in windows})
layout = pg(payload, 'layout')
if data == '-':
path = None
else:
f = set_background_image.current_file_obj
path = f.name
set_background_image.current_file_obj = None
f.flush()
try:
if layout:
set_background_image_impl(f.name, os_windows, pg(payload, 'configured'), layout)
set_background_image_impl(path, os_windows, pg(payload, 'configured'), layout)
else:
set_background_image_impl(f.name, os_windows, pg(payload, 'configured'))
set_background_image_impl(path, os_windows, pg(payload, 'configured'))
except ValueError as err:
err.hide_traceback = True
raise

View File

@ -919,22 +919,25 @@ pyset_background_image(PyObject *self UNUSED, PyObject *args) {
PyObject *layout_name = NULL;
PyObject *os_window_ids;
int configured = 0;
PA("sO!|pU", &path, &PyTuple_Type, &os_window_ids, &configured, &layout_name);
PA("zO!|pU", &path, &PyTuple_Type, &os_window_ids, &configured, &layout_name);
size_t size;
BackgroundImageLayout layout = layout_name ? bglayout(layout_name) : OPT(background_image_layout);
BackgroundImage *bgimage = calloc(1, sizeof(BackgroundImage));
if (!bgimage) return PyErr_NoMemory();
if (!png_path_to_bitmap(path, &bgimage->bitmap, &bgimage->width, &bgimage->height, &size)) {
PyErr_Format(PyExc_ValueError, "Failed to load image from: %s", path);
free(bgimage);
return NULL;
BackgroundImage *bgimage = NULL;
if (path) {
bgimage = calloc(1, sizeof(BackgroundImage));
if (!bgimage) return PyErr_NoMemory();
if (!png_path_to_bitmap(path, &bgimage->bitmap, &bgimage->width, &bgimage->height, &size)) {
PyErr_Format(PyExc_ValueError, "Failed to load image from: %s", path);
free(bgimage);
return NULL;
}
send_bgimage_to_gpu(layout, bgimage);
bgimage->refcnt++;
}
send_bgimage_to_gpu(layout, bgimage);
bgimage->refcnt++;
if (configured) {
free_bgimage(&global_state.bgimage, true);
global_state.bgimage = bgimage;
bgimage->refcnt++;
if (bgimage) bgimage->refcnt++;
OPT(background_image_layout) = layout;
}
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(os_window_ids); i++) {
@ -944,10 +947,10 @@ pyset_background_image(PyObject *self UNUSED, PyObject *args) {
free_bgimage(&os_window->bgimage, true);
os_window->bgimage = bgimage;
os_window->render_calls = 0;
bgimage->refcnt++;
if (bgimage) bgimage->refcnt++;
END_WITH_OS_WINDOW
}
free_bgimage(&bgimage, true);
if (bgimage) free_bgimage(&bgimage, true);
Py_RETURN_NONE;
}