A plug-and-play custom title bar and window manager for Pygame/Win32 apps on Windows
Project description
Easy Custom Titlebar
A plug-and-play, beautiful custom title bar and window manager for Pygame/Win32 apps on Windows. This package lets you add a modern, draggable, resizable, borderless window with custom minimize, maximize, and close buttons to your Pygame project—no prior experience required!
What is this?
Easy Custom Titlebar replaces the default Windows title bar in your Pygame app with a fully custom, modern one. It gives you:
- A borderless window with a custom title bar
- Native-feeling minimize, maximize, and close buttons (with icons)
- Drag-to-move and drag-to-resize window support
- Optional vertical scrolling support
- All required icons and assets included
- Simple, beginner-friendly API
You do NOT need to know anything about Windows APIs, Pygame window management, or custom drawing. Just follow the steps below!
Installation
-
Install with pip:
pip install easy_custom_titlebar
This will also install
pygameandpywin32if you don't have them. -
(Optional) If installing locally:
- Download or clone this repo.
- In the project folder, run:
pip install .
Quick Start Example
Create a new Python file (e.g., my_app.py) and paste this code:
from easy_custom_titlebar import CustomTitleBarWindow
def draw_content(screen, width, height, scroll_y):
import pygame
# Fill the area below the titlebar with a color
pygame.draw.rect(screen, (60, 80, 120), (0, window.titlebar_height, width, height-window.titlebar_height))
font = pygame.font.SysFont("Consolas", 24)
text = font.render(f"Hello, World! Scroll: {scroll_y}", True, (255, 255, 255))
screen.blit(text, (20, window.titlebar_height + 20))
if __name__ == "__main__":
window = CustomTitleBarWindow(width=800, height=500, title="My App", enable_scroll=True)
window.run(draw_content)
Run it with:
python my_app.py
You’ll see a modern window with a custom titlebar, working buttons, and your content below!
Full API Reference
Class: CustomTitleBarWindow
Constructor
CustomTitleBarWindow(
width=1200,
height=700,
title="",
enable_scroll=False,
titlebar_color=None,
button_color=None,
button_hover_color=None,
button_icon_color="white",
titlebar_border=False,
titlebar_border_color=(0,0,0),
titlebar_border_thickness=1,
titlebar_font_family="Consolas",
titlebar_font_size=28,
titlebar_font_bold=True,
left_notch_width=0,
titlebar_height=40,
close_button_color=(200,0,0),
close_button_hover_color=(255,0,0),
minmax_button_hover_color=None,
window_icon=None,
minimize_icon=None,
maximize_icon=None,
restore_icon=None,
close_icon=None,
custom_buttons=None
)
Parameter Details (Exhaustive)
| Parameter | Type | Default | Description |
|---|---|---|---|
| width | int | 1200 | Width of the window in pixels. |
| height | int | 700 | Height of the window in pixels. |
| title | str | "" | The text displayed in the titlebar. |
| enable_scroll | bool | False | If True, enables vertical scrolling via mouse wheel or arrow keys. The scroll value is passed to your draw_content function. |
| titlebar_color | tuple/str | (25,25,25) | Background color of the titlebar. Accepts an RGB tuple (e.g., (30,30,30)) or a hex string (e.g., "#1e1e1e"). |
| button_color | tuple/str | titlebar_color | Background color of the titlebar buttons. Accepts RGB tuple or hex string. |
| button_hover_color | tuple/str | (150,150,150) | Background color of buttons when hovered. |
| button_icon_color | str | "white" | Icon color for all titlebar buttons. Use "white" or "black". |
| titlebar_border | bool | False | If True, draws a border at the bottom of the titlebar. |
| titlebar_border_color | tuple | (0,0,0) | Color of the titlebar border (RGB tuple). |
| titlebar_border_thickness | int | 1 | Thickness of the titlebar border in pixels. |
| titlebar_font_family | str | "Consolas" | Font family for the titlebar text. Any font available on your system. |
| titlebar_font_size | int | 28 | Font size for the titlebar text. |
| titlebar_font_bold | bool | True | Whether the titlebar text is bold. |
| left_notch_width | int | 0 | Width in pixels to leave as a "notch" at the left of the titlebar (for a sidebar). |
| titlebar_height | int | 40 | Height of the titlebar in pixels. Set only at creation. |
| close_button_color | tuple | (200,0,0) | Background color of the close (X) button. |
| close_button_hover_color | tuple | (255,0,0) | Background color of the close button when hovered. |
| minmax_button_hover_color | tuple | (150,150,150) | Background color of minimize/maximize buttons when hovered. |
| window_icon | str/None | None | Path to a custom window/taskbar icon (PNG/ICO). If None, uses default. |
| minimize_icon | str/None | None | Path to a custom minimize button icon. If None, uses default. |
| maximize_icon | str/None | None | Path to a custom maximize button icon. If None, uses default. |
| restore_icon | str/None | None | Path to a custom restore button icon. If None, uses default. |
| close_icon | str/None | None | Path to a custom close button icon. If None, uses default. |
| custom_buttons | list[dict] | None | List of custom button dicts to add to the titlebar. Each dict can have: icon (path), label (str), tooltip (str), callback (function), and left (int, px offset from left). |
Parameter Usage Examples
- To set a dark blue titlebar:
titlebar_color=(10,20,40)ortitlebar_color="#0a1428" - To use black icons:
button_icon_color="black" - To add a sidebar notch:
left_notch_width=60 - To add a custom button:
def on_help(): print("Help clicked!") window = CustomTitleBarWindow(custom_buttons=[{"icon": "my_icon.png", "tooltip": "Help", "callback": on_help, "left": 200}])
Methods & Properties
run(draw_content=None)
- Starts the window’s main loop.
draw_contentis a function you provide that draws your app’s content. It should accept(screen, width, height, scroll_y).- The window handles all titlebar and button logic for you.
- Example:
def draw_content(screen, width, height, scroll_y): import pygame y_offset = window.titlebar_height pygame.draw.rect(screen, (100, 100, 200), (0, y_offset, width, height-y_offset)) font = pygame.font.SysFont("Arial", 24) text = font.render("This is my app!", True, (255,255,255)) screen.blit(text, (30, y_offset + 20)) window.run(draw_content)
set_title(title)
- Changes the window’s title text.
- Call this at any time to update the titlebar text.
- Example:
window.set_title("New Title")
maximize_window()
- Maximizes or restores the window.
- You can call this to programmatically maximize or restore the window.
- Example:
window.maximize_window()
minimize_window()
- Minimizes the window.
- Example:
window.minimize_window()
close_window()
- Closes the window.
- Example:
window.close_window()
titlebar_height (property)
- Returns the height of the titlebar.
- Read-only after creation. Use this to align your content below the titlebar.
- Example:
y_offset = window.titlebar_height pygame.draw.rect(screen, (60, 80, 120), (0, y_offset, width, height-y_offset))
Helper: resource_path(filename)
- Returns the absolute path to a built-in asset (icon/image) in the package.
- Use this to load icons from the package’s assets folder.
- Example:
from easy_custom_titlebar import resource_path icon_path = resource_path('close_white.png') my_icon = pygame.image.load(icon_path)
Usage Tips & Best Practices
- Always use
window.titlebar_heightto align your content below the titlebar. - Use the
custom_buttonsparameter to add extra buttons (e.g., Help, Settings) to the titlebar. - Use the
enable_scrollparameter if your content is scrollable. - For best results, use PNG icons with transparency for custom buttons.
- All color parameters accept both RGB tuples and hex strings.
- The titlebar height, font, and notch width are fixed at creation for reliability.
Parameter Details & Notes
- titlebar_color, button_color, button_hover_color: Accept either an RGB tuple (e.g.,
(30,30,30)) or a hex string (e.g.,"#1e1e1e"). If not set, sensible defaults are used. - button_icon_color: Use
"white"or"black"to select the icon variant for all buttons. - titlebar_border: If
True, draws a border at the bottom of the titlebar. You can customize its color and thickness. - titlebar_font_family, titlebar_font_size, titlebar_font_bold: Control the font used for the titlebar text.
- left_notch_width: If greater than 0, leaves a "notch" at the left of the titlebar for a sidebar. The notch area is filled with the window background color. To visually merge a sidebar, draw your sidebar in the content area at x=0, width=
left_notch_width. - titlebar_height: Set only at creation. All titlebar drawing, button placement, and content alignment will use this value. Cannot be changed after window creation.
- Button hitboxes and drawing: All button hitboxes and drawing are recalculated every frame, so they always match the current titlebar height and notch settings.
- All drawing is handled for you: You do not need to manually handle button clicks or titlebar logic—just use
window.run(draw_content).
How to Access the Built-in Icons/Assets
All icons (minimize, maximize, restore, close) are included in the package. To get the path to an asset:
from easy_custom_titlebar import resource_path
icon_path = resource_path('close_white.png')
You can use this path to load the icon in your own code if needed.
Troubleshooting & FAQ
Q: I get an error about missing DLLs or win32gui.
- Make sure you’re on Windows and have run
pip install easy_custom_titlebar(which installspywin32).
Q: The window doesn’t have rounded corners!
- Rounded corners require Windows 11. On older Windows, the window will still work, just with square corners.
Q: The buttons don’t show up or look weird.
- Make sure you’re not running in a virtual environment that blocks image loading, and that the assets are included (they are by default).
Q: How do I draw my own UI below the titlebar?
- Just use the
draw_contentfunction you pass torun(). Draw anything you want on thescreensurface, starting atwindow.titlebar_height(below the titlebar).
Q: Can I use this for a game?
- Yes! Just draw your game in
draw_content.
Q: Can I change the titlebar color or icons?
- You can edit the package’s assets or code, or fork the repo for more customization.
Q: Can I change the titlebar height after the window is created?
- No. For simplicity and reliability, the titlebar height is fixed at creation time.
Project Structure
Easy Custom Titlebar/
├── easy_custom_titlebar/
│ ├── __init__.py
│ ├── custom_titlebar.py
│ └── assets/
│ ├── *.png, *.ico
├── setup.py
├── MANIFEST.in
├── README.md
- easy_custom_titlebar/: Main package code and assets.
- assets/: All icons and images used by the titlebar.
- setup.py: Packaging and installation config.
- MANIFEST.in: Ensures assets are included in the package.
- README.md: Documentation and usage.
Contributing
Contributions are welcome! Please open an issue or pull request for bug fixes, new features, or documentation improvements.
- Fork the repo and create your branch from
main. - Add your feature or fix, and include tests if possible.
- Ensure your code is clean and well-documented.
- Submit a pull request with a clear description of your changes.
Code of Conduct
This project follows the Contributor Covenant Code of Conduct. Please be respectful and inclusive in all interactions.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file easy_custom_titlebar-2.0.1.tar.gz.
File metadata
- Download URL: easy_custom_titlebar-2.0.1.tar.gz
- Upload date:
- Size: 66.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c3e4af5dcbbb779e372d063da10698e3e06e5c512f966e2fd0166920f946e4c
|
|
| MD5 |
5a70399352eca9ba4328f3570436c087
|
|
| BLAKE2b-256 |
c9a83def490cc7ce0ce7ade36b1170f64c98f62d9becd545ad4084fe26bdc233
|
File details
Details for the file easy_custom_titlebar-2.0.1-py3-none-any.whl.
File metadata
- Download URL: easy_custom_titlebar-2.0.1-py3-none-any.whl
- Upload date:
- Size: 63.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40b0019dc1d59062236960bf2e53845fb64b2f85dcc513a199da74bf155ff698
|
|
| MD5 |
ed98bd434cc7dcf185a842e9e9779749
|
|
| BLAKE2b-256 |
e8ef20d098fe698e7806201ef1a62dbcfadab88a7dfbf54f97b4512232fb7669
|