Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions .github/ISSUE_TEMPLATE/bug_report.md

This file was deleted.

87 changes: 87 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Bug report
description: Report a reproducible problem in Termix
title: "[Bug] "
labels:
- bug
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report a bug.

Please provide enough detail for us to reproduce and diagnose the issue.

- type: textarea
id: summary
attributes:
label: Summary
description: Describe the bug clearly and concisely.
validations:
required: true

- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: List the exact steps needed to reproduce the issue.
placeholder: |
1. Open ...
2. Tap or run ...
3. Observe ...
validations:
required: true

- type: textarea
id: expected
attributes:
label: Expected behavior
description: Describe what you expected to happen.
validations:
required: true

- type: textarea
id: actual
attributes:
label: Actual behavior
description: Describe what actually happened instead.
validations:
required: true

- type: textarea
id: environment
attributes:
label: Environment
description: Provide the environment details used when the bug occurred.
value: |
- Device:
- ROM / OS:
- Android version:
- Termix version:
- Install source:
validations:
required: true

- type: textarea
id: logs
attributes:
label: Logs
description: Paste any relevant logcat output, stack trace, or error message.
render: shell
validations:
required: false

- type: textarea
id: media
attributes:
label: Screenshots or screen recordings
description: Add links or short notes for any screenshots or recordings that help explain the issue.
validations:
required: false

- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context that may help reproduce or diagnose the problem.
validations:
required: false
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Termix README
url: https://github.com/jeffusion/Termix#readme
about: Read the project overview, build instructions, and screenshots before opening an issue.
20 changes: 0 additions & 20 deletions .github/ISSUE_TEMPLATE/feature_request.md

This file was deleted.

60 changes: 60 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Feature request
description: Suggest an improvement or new capability for Termix
title: "[Feature] "
labels:
- enhancement
body:
- type: markdown
attributes:
value: |
Thanks for suggesting an improvement for Termix.

Please explain the problem, proposed solution, and why it matters.

- type: textarea
id: problem
attributes:
label: Problem statement
description: Describe the problem or limitation you are trying to solve.
validations:
required: true

- type: textarea
id: solution
attributes:
label: Proposed solution
description: Describe the behavior, workflow, or feature you would like to see.
validations:
required: true

- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: Describe any alternative solutions, workarounds, or designs you have considered.
validations:
required: false

- type: textarea
id: use-case
attributes:
label: Use case
description: Explain why this would be valuable for users or contributors.
validations:
required: true

- type: checkboxes
id: checks
attributes:
label: Before submitting
options:
- label: I searched the existing issues to avoid creating a duplicate request.
required: true

- type: textarea
id: additional
attributes:
label: Additional context
description: Add any mockups, screenshots, references, or extra context here.
validations:
required: false
16 changes: 16 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Summary

-

## Testing

- [ ] Not run
- [ ] Built locally
- [ ] Tested on device/emulator

## Checklist

- [ ] My changes are scoped and relevant to this PR
- [ ] I updated documentation when needed
- [ ] I verified the affected behavior locally
- [ ] I did not include unrelated changes
60 changes: 51 additions & 9 deletions scripts/generate_launcher_icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import argparse
from pathlib import Path
from typing import cast

from PIL import Image

Expand All @@ -26,6 +27,11 @@
BACKGROUND_COLOR = (12, 15, 16, 255)
FOREGROUND_SCALE = 0.80
MONOCHROME_SCALE = 0.55
BACKGROUND_DISTANCE_THRESHOLD = 28


def get_rgba_pixel(image: Image.Image, x: int, y: int) -> tuple[int, int, int, int]:
return cast(tuple[int, int, int, int], image.getpixel((x, y)))


def render_contain(
Expand All @@ -45,23 +51,59 @@ def render_contain(


def build_monochrome_mask(source: Image.Image) -> Image.Image:
rgba = source.load()
monochrome = Image.new("RGBA", source.size, (255, 255, 255, 0))
mono_pixels = monochrome.load()

for y in range(source.height):
for x in range(source.width):
r, g, b, a = rgba[x, y]
edge_samples: list[tuple[int, int, int]] = []
width = source.width
height = source.height

for x in range(width):
for y in (0, height - 1):
r, g, b, a = get_rgba_pixel(source, x, y)
if a > 0:
edge_samples.append((r, g, b))

for y in range(height):
for x in (0, width - 1):
r, g, b, a = get_rgba_pixel(source, x, y)
if a > 0:
edge_samples.append((r, g, b))

background_color: tuple[int, int, int] | None = None
if edge_samples:
red, green, blue = (
round(sum(channel) / len(edge_samples)) for channel in zip(*edge_samples)
)
background_color = (red, green, blue)

for y in range(height):
for x in range(width):
r, g, b, a = get_rgba_pixel(source, x, y)
if a == 0:
continue

luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b
if g > 110 and g > r + 25 and g > b + 20 and luminance > 70:
mono_pixels[x, y] = (255, 255, 255, 255)
if background_color is None:
monochrome.putpixel((x, y), (255, 255, 255, 255))
continue

color_distance = sum(
abs(channel - background_channel)
for channel, background_channel in zip((r, g, b), background_color)
)
if color_distance >= BACKGROUND_DISTANCE_THRESHOLD:
monochrome.putpixel((x, y), (255, 255, 255, 255))

bbox = monochrome.getbbox()
if bbox is None:
raise RuntimeError("Unable to derive monochrome launcher icon from source logo")
alpha_mask = source.getchannel("A")
bbox = alpha_mask.getbbox()
if bbox is None:
raise RuntimeError(
"Unable to derive monochrome launcher icon from source logo"
)

monochrome = Image.new("RGBA", source.size, (255, 255, 255, 0))
monochrome.putalpha(alpha_mask)

return monochrome.crop(bbox)

Expand Down
Loading