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 {{{ # set_background_image {{{
@cmd( @cmd(
'Set the background_image', '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='''\ options_spec='''\
--all -a --all -a
type=bool-set 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): 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 img_id+: Unique uuid (as string) used for chunking
match: Window to change opacity in match: Window to change opacity in
layout: The image layout 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') raise SystemExit('Must specify path to PNG image')
path = args[0] path = args[0]
ret = {'match': opts.match, 'configured': opts.configured, 'layout': opts.layout, 'all': opts.all, 'img_id': str(uuid4())} 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': if imghdr.what(path) != 'png':
raise SystemExit('{} is not a PNG image'.format(path)) raise SystemExit('{} is not a PNG image'.format(path))
@ -1321,25 +1327,31 @@ def set_background_image(boss, window, payload):
import tempfile import tempfile
pg = cmd_set_background_image.payload_get pg = cmd_set_background_image.payload_get
data = pg(payload, 'data') data = pg(payload, 'data')
img_id = pg(payload, 'img_id') if data != '-':
if img_id != set_background_image.current_img_id: img_id = pg(payload, 'img_id')
set_background_image.current_img_id = img_id if img_id != set_background_image.current_img_id:
set_background_image.current_file_obj = tempfile.NamedTemporaryFile() set_background_image.current_img_id = img_id
if data: set_background_image.current_file_obj = tempfile.NamedTemporaryFile()
set_background_image.current_file_obj.write(standard_b64decode(data)) if data:
return no_response 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) windows = windows_for_payload(boss, window, payload)
os_windows = tuple({w.os_window_id for w in windows}) os_windows = tuple({w.os_window_id for w in windows})
layout = pg(payload, 'layout') 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: try:
if layout: 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: 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: except ValueError as err:
err.hide_traceback = True err.hide_traceback = True
raise raise

View File

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