Use the new async response framework when setting background/logo images via RC. Avoids having to use --no-response
This commit is contained in:
parent
e91c008357
commit
3f0ecbb241
@ -5,9 +5,11 @@ import imghdr
|
||||
import os
|
||||
import tempfile
|
||||
from base64 import standard_b64decode, standard_b64encode
|
||||
from typing import IO, TYPE_CHECKING, Optional
|
||||
from typing import IO, TYPE_CHECKING, Dict, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from kitty.types import AsyncResponse
|
||||
|
||||
from .base import (
|
||||
MATCH_WINDOW_OPTION, ArgsType, Boss, CmdGenerator, PayloadGetType,
|
||||
PayloadType, RCOptions, RemoteCommand, ResponseType, Window
|
||||
@ -22,7 +24,6 @@ class SetBackgroundImage(RemoteCommand):
|
||||
'''
|
||||
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
|
||||
all: Boolean indicating operate on all windows
|
||||
@ -62,8 +63,8 @@ failed, the command will exit with a success code.
|
||||
argspec = 'PATH_TO_PNG_IMAGE'
|
||||
args_count = 1
|
||||
args_completion = {'files': ('PNG Images', ('*.png',))}
|
||||
current_img_id: Optional[str] = None
|
||||
current_file_obj: Optional[IO[bytes]] = None
|
||||
images_in_flight: Dict[str, IO[bytes]] = {}
|
||||
is_asynchronous = True
|
||||
|
||||
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
|
||||
if len(args) != 1:
|
||||
@ -96,15 +97,13 @@ failed, the command will exit with a success code.
|
||||
|
||||
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
||||
data = payload_get('data')
|
||||
img_id = payload_get('async_id')
|
||||
if data != '-':
|
||||
img_id = payload_get('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 img_id not in self.images_in_flight:
|
||||
self.images_in_flight[img_id] = tempfile.NamedTemporaryFile()
|
||||
if data:
|
||||
assert set_background_image.current_file_obj is not None
|
||||
set_background_image.current_file_obj.write(standard_b64decode(data))
|
||||
return None
|
||||
self.images_in_flight[img_id].write(standard_b64decode(data))
|
||||
return AsyncResponse()
|
||||
|
||||
windows = self.windows_for_payload(boss, window, payload_get)
|
||||
os_windows = tuple({w.os_window_id for w in windows})
|
||||
@ -112,10 +111,8 @@ failed, the command will exit with a success code.
|
||||
if data == '-':
|
||||
path = None
|
||||
else:
|
||||
assert set_background_image.current_file_obj is not None
|
||||
f = set_background_image.current_file_obj
|
||||
f = self.images_in_flight.pop(img_id)
|
||||
path = f.name
|
||||
set_background_image.current_file_obj = None
|
||||
f.flush()
|
||||
|
||||
try:
|
||||
@ -125,5 +122,9 @@ failed, the command will exit with a success code.
|
||||
raise
|
||||
return None
|
||||
|
||||
def cancel_async_request(self, boss: 'Boss', window: Optional['Window'], payload_get: PayloadGetType) -> None:
|
||||
async_id = payload_get('async_id')
|
||||
self.images_in_flight.pop(async_id, None)
|
||||
|
||||
|
||||
set_background_image = SetBackgroundImage()
|
||||
|
||||
@ -6,9 +6,11 @@ import imghdr
|
||||
import os
|
||||
import tempfile
|
||||
from base64 import standard_b64decode, standard_b64encode
|
||||
from typing import IO, TYPE_CHECKING, Optional
|
||||
from typing import IO, TYPE_CHECKING, Dict, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
from kitty.types import AsyncResponse
|
||||
|
||||
from .base import (
|
||||
MATCH_WINDOW_OPTION, ArgsType, Boss, CmdGenerator, PayloadGetType,
|
||||
PayloadType, RCOptions, RemoteCommand, ResponseType, Window
|
||||
@ -62,8 +64,8 @@ failed, the command will exit with a success code.
|
||||
argspec = 'PATH_TO_PNG_IMAGE'
|
||||
args_count = 1
|
||||
args_completion = {'files': ('PNG Images', ('*.png',))}
|
||||
current_img_id: Optional[str] = None
|
||||
current_file_obj: Optional[IO[bytes]] = None
|
||||
images_in_flight: Dict[str, IO[bytes]] = {}
|
||||
is_asynchronous = True
|
||||
|
||||
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
|
||||
if len(args) != 1:
|
||||
@ -96,23 +98,19 @@ failed, the command will exit with a success code.
|
||||
|
||||
def response_from_kitty(self, boss: Boss, window: Optional[Window], payload_get: PayloadGetType) -> ResponseType:
|
||||
data = payload_get('data')
|
||||
img_id = payload_get('async_id')
|
||||
if data != '-':
|
||||
img_id = payload_get('img_id')
|
||||
if img_id != self.current_img_id:
|
||||
self.current_img_id = img_id
|
||||
self.current_file_obj = tempfile.NamedTemporaryFile(suffix='.png')
|
||||
if img_id not in self.images_in_flight:
|
||||
self.images_in_flight[img_id] = tempfile.NamedTemporaryFile()
|
||||
if data:
|
||||
assert self.current_file_obj is not None
|
||||
self.current_file_obj.write(standard_b64decode(data))
|
||||
return None
|
||||
self.images_in_flight[img_id].write(standard_b64decode(data))
|
||||
return AsyncResponse()
|
||||
|
||||
if data == '-':
|
||||
path = ''
|
||||
else:
|
||||
assert self.current_file_obj is not None
|
||||
f = self.current_file_obj
|
||||
f = self.images_in_flight.pop(img_id)
|
||||
path = f.name
|
||||
self.current_file_obj = None
|
||||
f.flush()
|
||||
|
||||
alpha = float(payload_get('alpha', '-1'))
|
||||
|
||||
@ -45,12 +45,12 @@ def handle_cmd(boss: BossType, window: Optional[WindowType], serialized_cmd: str
|
||||
payload['peer_id'] = peer_id
|
||||
async_id = str(cmd.get('async', ''))
|
||||
if async_id:
|
||||
payload['async_id'] = async_id
|
||||
if 'cancel_async' in cmd:
|
||||
active_async_requests.pop(async_id, None)
|
||||
c.cancel_async_request(boss, window, PayloadGetter(c, payload))
|
||||
return None
|
||||
active_async_requests[async_id] = monotonic()
|
||||
payload['async_id'] = async_id
|
||||
if len(active_async_requests) > 32:
|
||||
oldest = next(iter(active_async_requests))
|
||||
del active_async_requests[oldest]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user