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