Загрузка данных


"""
Таскбар Windows 10 как продолжение картинки окна.

Как работает: таскбар делается полностью прозрачным, а прямо под ним
рисуется полоска из растянутых нижних пикселей окна. Иконки остаются сверху.

Установка:  pip install pillow
Запуск:     python taskbar_continue.py
Остановка:  Ctrl+C или диспетчер задач (pythonw.exe)

Важно: не запускай одновременно с taskbar_color.py.
В Open-Shell отключи «Настроить панель задач» (иначе будет конфликт).
"""
import ctypes
import time
import tkinter as tk
from ctypes import wintypes

from PIL import Image, ImageFilter, ImageGrab, ImageTk

# --- настройки ---
INTERVAL_MS = 40     # частота обновления (40 мс ~ 25 кадров/сек)
SAMPLE_PX = 4        # сколько нижних строк окна берём для растяжки
BLUR = 0             # размытие растянутой полоски (0 = без размытия)
MODE = "stretch"     # "stretch" = растянуть низ окна, "mirror" = отражение

user32 = ctypes.windll.user32
user32.SetProcessDPIAware()

H = wintypes.HWND
user32.FindWindowW.restype = H
user32.FindWindowW.argtypes = [wintypes.LPCWSTR, wintypes.LPCWSTR]
user32.GetForegroundWindow.restype = H
user32.GetParent.restype = H
user32.GetParent.argtypes = [H]
user32.IsWindow.argtypes = [H]
user32.IsIconic.argtypes = [H]
user32.GetWindowRect.argtypes = [H, ctypes.POINTER(wintypes.RECT)]
user32.GetClassNameW.argtypes = [H, wintypes.LPWSTR, ctypes.c_int]
user32.GetWindowLongW.argtypes = [H, ctypes.c_int]
user32.SetWindowLongW.argtypes = [H, ctypes.c_int, ctypes.c_long]
user32.SetWindowPos.argtypes = [
    H, H, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, wintypes.UINT
]

GWL_EXSTYLE = -20
WS_EX_TOOLWINDOW = 0x00000080
WS_EX_NOACTIVATE = 0x08000000
WS_EX_TRANSPARENT = 0x00000020
SWP_NOACTIVATE = 0x0010
SWP_SHOWWINDOW = 0x0040


class ACCENT_POLICY(ctypes.Structure):
    _fields_ = [
        ("AccentState", ctypes.c_int),
        ("AccentFlags", ctypes.c_int),
        ("GradientColor", ctypes.c_uint),
        ("AnimationId", ctypes.c_int),
    ]


class WCA_DATA(ctypes.Structure):
    _fields_ = [
        ("Attribute", ctypes.c_int),
        ("Data", ctypes.POINTER(ACCENT_POLICY)),
        ("SizeOfData", ctypes.c_size_t),
    ]


user32.SetWindowCompositionAttribute.argtypes = [H, ctypes.POINTER(WCA_DATA)]

ACCENT_DISABLED = 0
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2


def set_accent(hwnd, state, a=0, r=0, g=0, b=0):
    color = (a << 24) | (b << 16) | (g << 8) | r
    policy = ACCENT_POLICY(state, 2, color, 0)
    data = WCA_DATA(19, ctypes.pointer(policy), ctypes.sizeof(policy))
    user32.SetWindowCompositionAttribute(hwnd, ctypes.byref(data))


def get_class(hwnd):
    buf = ctypes.create_unicode_buffer(256)
    user32.GetClassNameW(hwnd, buf, 256)
    return buf.value


def get_rect(hwnd):
    r = wintypes.RECT()
    user32.GetWindowRect(hwnd, ctypes.byref(r))
    return r.left, r.top, r.right, r.bottom


def build_strip(left, top, right, w, h):
    """Картинка для таскбара из пикселей прямо над ним."""
    if MODE == "mirror":
        img = ImageGrab.grab(bbox=(left, top - h, right, top)).convert("RGB")
        img = img.transpose(Image.FLIP_TOP_BOTTOM)
    else:
        img = ImageGrab.grab(bbox=(left, top - SAMPLE_PX, right, top)).convert("RGB")
        img = img.resize((w, h), Image.BILINEAR)
    if BLUR:
        img = img.filter(ImageFilter.GaussianBlur(BLUR))
    return img


def main():
    taskbar = None
    while not taskbar:
        taskbar = user32.FindWindowW("Shell_TrayWnd", None)
        if not taskbar:
            time.sleep(1)

    root = tk.Tk()
    root.overrideredirect(True)
    root.attributes("-topmost", True)
    root.configure(bg="black")
    label = tk.Label(root, bd=0, highlightthickness=0, bg="black")
    label.pack(fill="both", expand=True)
    root.update_idletasks()

    hwnd = user32.GetParent(root.winfo_id()) or root.winfo_id()
    style = user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
    user32.SetWindowLongW(
        hwnd, GWL_EXSTYLE,
        style | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE | WS_EX_TRANSPARENT,
    )

    skip_classes = {"Shell_TrayWnd", "Progman", "WorkerW", "Windows.UI.Core.CoreWindow"}
    state = {"taskbar": taskbar, "last_accent": 0.0, "photo": None, "visible": False}

    def hide():
        if state["visible"]:
            root.withdraw()
            state["visible"] = False

    def tick():
        try:
            tb = state["taskbar"]
            if not user32.IsWindow(tb):
                tb = user32.FindWindowW("Shell_TrayWnd", None)
                state["taskbar"] = tb
                if not tb:
                    hide()
                    return

            left, top, right, bottom = get_rect(tb)
            w, h = right - left, bottom - top

            # раз в полсекунды заново делаем таскбар прозрачным
            now = time.time()
            if now - state["last_accent"] > 0.5:
                set_accent(tb, ACCENT_ENABLE_TRANSPARENTGRADIENT, 0, 0, 0, 0)
                state["last_accent"] = now

            fg = user32.GetForegroundWindow()
            ok = (
                fg
                and get_class(fg) not in skip_classes
                and not user32.IsIconic(fg)
                and w > h        # только горизонтальный таскбар
                and top > 100    # и только внизу экрана
            )
            if not ok:
                hide()
                return

            img = build_strip(left, top, right, w, h)
            photo = ImageTk.PhotoImage(img)
            label.configure(image=photo)
            state["photo"] = photo  # держим ссылку, иначе картинка пропадёт

            root.geometry(f"{w}x{h}+{left}+{top}")
            if not state["visible"]:
                root.deiconify()
                state["visible"] = True
            # ставим окно сразу под таскбаром
            user32.SetWindowPos(hwnd, tb, left, top, w, h,
                                SWP_NOACTIVATE | SWP_SHOWWINDOW)
        except Exception:
            pass
        finally:
            root.after(INTERVAL_MS, tick)

    root.after(0, tick)
    try:
        root.mainloop()
    except KeyboardInterrupt:
        pass
    finally:
        try:
            set_accent(state["taskbar"], ACCENT_DISABLED)
        except Exception:
            pass


if __name__ == "__main__":
    main()