@@ -320,6 +320,9 @@ def query_best_size(self, item_class, width, height):
320320class Window (Drawable ):
321321 __window__ = resource .Resource .__resource__
322322
323+ _STRING_ENCODING = 'ISO-8859-1'
324+ _UTF8_STRING_ENCODING = 'UTF-8'
325+
323326 def create_window (self , x , y , width , height , border_width , depth ,
324327 window_class = X .CopyFromParent ,
325328 visual = X .CopyFromParent ,
@@ -432,6 +435,16 @@ def change_property(self, property, property_type, format, data,
432435 type = property_type ,
433436 data = (format , data ))
434437
438+ def change_text_property (self , property , property_type , data ,
439+ mode = X .PropModeReplace , onerror = None ):
440+ if not isinstance (data , bytes ):
441+ if property_type == Xatom .STRING :
442+ data = data .encode (self ._STRING_ENCODING )
443+ elif property_type == self .display .get_atom ('UTF8_STRING' ):
444+ data = data .encode (self ._UTF8_STRING_ENCODING )
445+ self .change_property (property , property_type , 8 , data ,
446+ mode = mode , onerror = onerror )
447+
435448 def delete_property (self , property , onerror = None ):
436449 request .DeleteProperty (display = self .display ,
437450 onerror = onerror ,
@@ -469,6 +482,19 @@ def get_full_property(self, property, property_type, sizehint = 10):
469482 else :
470483 return None
471484
485+ def get_full_text_property (self , property , property_type = X .AnyPropertyType , sizehint = 10 ):
486+ prop = self .get_full_property (property , property_type ,
487+ sizehint = sizehint )
488+ if prop is None or prop .format != 8 :
489+ return None
490+ if prop .property_type == Xatom .STRING :
491+ prop .value = prop .value .decode (self ._STRING_ENCODING )
492+ elif prop .property_type == self .display .get_atom ('UTF8_STRING' ):
493+ prop .value = prop .value .decode (self ._UTF8_STRING_ENCODING )
494+ # FIXME: at least basic support for compound text would be nice.
495+ # elif prop.property_type == self.display.get_atom('COMPOUND_TEXT'):
496+ return prop .value
497+
472498 def list_properties (self ):
473499 r = request .ListProperties (display = self .display ,
474500 window = self .id )
@@ -636,43 +662,33 @@ def rotate_properties(self, properties, delta, onerror = None):
636662 properties = properties )
637663
638664 def set_wm_name (self , name , onerror = None ):
639- self .change_property (Xatom .WM_NAME , Xatom .STRING , 8 , name ,
640- onerror = onerror )
665+ self .change_text_property (Xatom .WM_NAME , Xatom .STRING , name ,
666+ onerror = onerror )
641667
642668 def get_wm_name (self ):
643- d = self .get_full_property (Xatom .WM_NAME , Xatom .STRING )
644- if d is None or d .format != 8 :
645- return None
646- else :
647- return d .value
669+ return self .get_full_text_property (Xatom .WM_NAME , Xatom .STRING )
648670
649671 def set_wm_icon_name (self , name , onerror = None ):
650- self .change_property (Xatom .WM_ICON_NAME , Xatom .STRING , 8 , name ,
651- onerror = onerror )
672+ self .change_text_property (Xatom .WM_ICON_NAME , Xatom .STRING , name ,
673+ onerror = onerror )
652674
653675 def get_wm_icon_name (self ):
654- d = self .get_full_property (Xatom .WM_ICON_NAME , Xatom .STRING )
655- if d is None or d .format != 8 :
656- return None
657- else :
658- return d .value
659-
676+ return self .get_full_text_property (Xatom .WM_ICON_NAME , Xatom .STRING )
660677
661678 def set_wm_class (self , inst , cls , onerror = None ):
662- self .change_property (Xatom .WM_CLASS , Xatom .STRING , 8 ,
663- '%s\0 %s\0 ' % (inst , cls ),
664- onerror = onerror )
679+ self .change_text_property (Xatom .WM_CLASS , Xatom .STRING ,
680+ '%s\0 %s\0 ' % (inst , cls ),
681+ onerror = onerror )
665682
666683 def get_wm_class (self ):
667- d = self .get_full_property (Xatom .WM_CLASS , Xatom .STRING )
668- if d is None or d .format != 8 :
684+ value = self .get_full_text_property (Xatom .WM_CLASS , Xatom .STRING )
685+ if value is None :
686+ return None
687+ parts = value .split ('\0 ' )
688+ if len (parts ) < 2 :
669689 return None
670690 else :
671- parts = d .value .split ('\0 ' )
672- if len (parts ) < 2 :
673- return None
674- else :
675- return parts [0 ], parts [1 ]
691+ return parts [0 ], parts [1 ]
676692
677693 def set_wm_transient_for (self , window , onerror = None ):
678694 self .change_property (Xatom .WM_TRANSIENT_FOR , Xatom .WINDOW ,
@@ -718,15 +734,11 @@ def get_wm_colormap_windows(self):
718734
719735
720736 def set_wm_client_machine (self , name , onerror = None ):
721- self .change_property (Xatom .WM_CLIENT_MACHINE , Xatom .STRING , 8 , name ,
722- onerror = onerror )
737+ self .change_text_property (Xatom .WM_CLIENT_MACHINE , Xatom .STRING , name ,
738+ onerror = onerror )
723739
724740 def get_wm_client_machine (self ):
725- d = self .get_full_property (Xatom .WM_CLIENT_MACHINE , Xatom .STRING )
726- if d is None or d .format != 8 :
727- return None
728- else :
729- return d .value
741+ return self .get_full_text_property (Xatom .WM_CLIENT_MACHINE , Xatom .STRING )
730742
731743 def set_wm_normal_hints (self , hints = {}, onerror = None , ** keys ):
732744 self ._set_struct_prop (Xatom .WM_NORMAL_HINTS , Xatom .WM_SIZE_HINTS ,
0 commit comments