window: fix bad looking icon on Windows 7 by using native win32 API and set different icon for SMALL and BIG profile. You need to provide a .ico along the .png, and must contain at a 16x16 and 48x48 image. Closes #1667

This commit is contained in:
Mathieu Virbel 2013-12-30 06:00:29 +01:00
parent 3b5b31cdd9
commit e0f59eb166
3 changed files with 58 additions and 17 deletions

View File

@ -1,7 +1,7 @@
include *AUTHORS *LICENSE include *AUTHORS *LICENSE
recursive-include doc * recursive-include doc *
recursive-include examples * recursive-include examples *
recursive-include kivy/data *.png *.jpg *.ttf *.kv *.fs *.vs *.json *.gif *.atlas recursive-include kivy/data *.png *.jpg *.ttf *.kv *.fs *.vs *.json *.gif *.atlas *.ico
recursive-include kivy/tools *.png *.txt *.bat *.sh *.py recursive-include kivy/tools *.png *.txt *.bat *.sh *.py
recursive-include kivy/tests *.py *.png recursive-include kivy/tests *.py *.png
recursive-include kivy *.pyd *.pyx *.c *.pxi *.h *.pxd recursive-include kivy *.pyd *.pyx *.c *.pxi *.h *.pxd

View File

@ -13,11 +13,12 @@ from kivy.core import CoreCriticalException
from os import environ from os import environ
from os.path import exists, join from os.path import exists, join
from kivy.config import Config from kivy.config import Config
from kivy import kivy_home_dir from kivy import kivy_data_dir
from kivy.base import ExceptionManager from kivy.base import ExceptionManager
from kivy.logger import Logger from kivy.logger import Logger
from kivy.base import stopTouchApp, EventLoop from kivy.base import stopTouchApp, EventLoop
from kivy.utils import platform from kivy.utils import platform
from kivy.resources import resource_find
# When we are generating documentation, Config doesn't exist # When we are generating documentation, Config doesn't exist
_exit_on_escape = True _exit_on_escape = True
@ -106,12 +107,16 @@ class WindowPygame(WindowBase):
# set window icon before calling set_mode # set window icon before calling set_mode
try: try:
#filename_icon = Config.get('kivy', 'window_icon')
filename_icon = self.icon or Config.get('kivy', 'window_icon') filename_icon = self.icon or Config.get('kivy', 'window_icon')
if filename_icon == '': if filename_icon == '':
logo_size = 512 if platform == 'macosx' else 32 logo_size = 32
filename_icon = join(kivy_home_dir, if platform == 'macosx':
'icon', 'kivy-icon-%d.png' % logo_size) logo_size = 512
elif platform == 'win':
logo_size = 64
filename_icon = 'kivy-icon-{}.png'.format(logo_size)
filename_icon = resource_find(
join(kivy_data_dir, 'logo', filename_icon))
self.set_icon(filename_icon) self.set_icon(filename_icon)
except: except:
Logger.exception('Window: cannot set icon') Logger.exception('Window: cannot set icon')
@ -183,23 +188,59 @@ class WindowPygame(WindowBase):
pygame.display.set_caption(self.title) pygame.display.set_caption(self.title)
def set_icon(self, filename): def set_icon(self, filename):
if not exists(filename):
return False
try: try:
if not exists(filename): if platform == 'win':
return False
if PY2:
try: try:
im = pygame.image.load(filename) if self._set_icon_win(filename):
except UnicodeEncodeError: return True
im = pygame.image.load(filename.encode('utf8')) except:
else: # fallback on standard loading then.
im = pygame.image.load(filename) pass
if im is None:
raise Exception('Unable to load window icon (not found)') # for all others platform, or if the ico is not available, use the
pygame.display.set_icon(im) # default way to set it.
self._set_icon_standard(filename)
super(WindowPygame, self).set_icon(filename) super(WindowPygame, self).set_icon(filename)
except: except:
Logger.exception('WinPygame: unable to set icon') Logger.exception('WinPygame: unable to set icon')
def _set_icon_standard(self, filename):
if PY2:
try:
im = pygame.image.load(filename)
except UnicodeEncodeError:
im = pygame.image.load(filename.encode('utf8'))
else:
im = pygame.image.load(filename)
if im is None:
raise Exception('Unable to load window icon (not found)')
pygame.display.set_icon(im)
def _set_icon_win(self, filename):
# ensure the window ico is ended by ico
if not filename.endswith('.ico'):
filename = '{}.ico'.format(filename.rsplit('.', 1)[0])
if not exists(filename):
return False
import win32api
import win32gui
import win32con
hwnd = pygame.display.get_wm_info()['window']
icon_big = win32gui.LoadImage(
None, filename, win32con.IMAGE_ICON,
48, 48, win32con.LR_LOADFROMFILE)
icon_small = win32gui.LoadImage(
None, filename, win32con.IMAGE_ICON,
16, 16, win32con.LR_LOADFROMFILE)
win32api.SendMessage(
hwnd, win32con.WM_SETICON, win32con.ICON_SMALL, icon_small)
win32api.SendMessage(
hwnd, win32con.WM_SETICON, win32con.ICON_BIG, icon_big)
return True
def screenshot(self, *largs, **kwargs): def screenshot(self, *largs, **kwargs):
global glReadPixels, GL_RGBA, GL_UNSIGNED_BYTE global glReadPixels, GL_RGBA, GL_UNSIGNED_BYTE
filename = super(WindowPygame, self).screenshot(*largs, **kwargs) filename = super(WindowPygame, self).screenshot(*largs, **kwargs)

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB