Score:2

จะตรวจสอบเหตุการณ์ของแอปพลิเคชัน เช่น เปิด ปิด ย่อขนาดใน Ubuntu ได้อย่างไร

ธง cc

ฉันต้องการทราบว่าเป็นไปได้หรือไม่ที่จะตรวจสอบการเปิด/ปิด/ย่อเหตุการณ์ของแอปพลิเคชันใน Ubuntu เป้าหมายแรกของฉันคือการตรวจสอบจำนวนครั้งที่ฉันเปิดโทรเลขเพื่อตรวจสอบข้อความ

PS: ฉันใช้ Ubuntu 20.04LTS (X11)

Jacob Vlijm avatar
by flag
ขึ้นอยู่กับว่าคุณอยู่ใน X (ไม่ใช่ทางบก) หรือไม่?
Sasha R Adler avatar
cc flag
@JacobVlijm ใช่ X11 ไม่ใช่ที่รกร้างว่างเปล่า
Jacob Vlijm avatar
by flag
เป็นไปได้ดีมาก ต้องการสคริปต์และคำอธิบายบางอย่าง ฉันจะเขียนตัวอย่างเล็ก ๆ ถ้าไม่มีใครเร็วกว่าฉัน :) แต่ไม่แน่ใจว่าเป็นวันนี้หรือไม่
Score:3
ธง by

เพื่อความสนุก เนื่องจากคุณอยู่บน X

การใช้ python (หรือภาษาอื่น ๆ มากมาย) เราสามารถใช้สัญญาณจาก Wnck.หน้าจอ และ Wnck.หน้าต่าง เพื่อจับตาดูการสร้างและ/หรือสถานะการเปลี่ยนแปลงของหน้าต่าง ซึ่งรวมถึงการขยายและย่อขนาดหน้าต่างให้ใหญ่สุด

นั่นคือสิ่งที่สคริปต์ด้านล่างทำ ต่อจากนั้น จะรักษาล็อกไฟล์ ซึ่งจะได้รับการอัปเดตหากคุณสร้าง ย่อหรือยกเลิกการย่อขนาดหน้าต่างของ WM_CLASS เฉพาะ (และแอปพลิเคชันอื่นๆ) คุณสามารถค้นหา WMCLASS ของแอปพลิเคชันเป้าหมายได้โดยเปิดเทอร์มินัล พิมพ์ xprop WM_CLASS + กลับจากนั้นคลิกที่ windowssubject ("telegramdesktop" สำหรับโทรเลขหรืออะไรทำนองนั้น)

โปรดทราบว่าฉันทำให้สคริปต์รีเซ็ตไฟล์บันทึกหลังจากแต่ละเซสชัน (การบันทึก) มิฉะนั้นไฟล์บันทึกจะใหญ่ขึ้นเมื่อเวลาผ่านไป

มีอะไรอยู่ในล็อกไฟล์?

ไฟล์บันทึก (~/.windowlog.txt) จะเก็บบันทึกการสร้าง การปิด และการเปลี่ยนสถานะของหน้าต่างของ WM_Class ที่กำหนด แต่ละครั้งที่หน้าต่างไม่ลดขนาด ตัวนับจะเพิ่มหนึ่งหน้าต่าง ดังนั้นเมื่อสิ้นสุดวัน คุณจะเห็นกิจกรรม:

พบหน้าต่าง: โทรเลข
เปลี่ยนสถานะแล้ว: ภาพ (1)
สถานะเปลี่ยน: ย่อเล็กสุด
เปลี่ยนสถานะแล้ว: ภาพ (2)
สถานะเปลี่ยน: ย่อเล็กสุด
เปลี่ยนสถานะแล้ว: ภาพ (3)
ปิดหน้าต่าง:โทรเลข
หน้าต่างใหม่:โทรเลข
เปลี่ยนสถานะแล้ว: ภาพ (4)
สถานะเปลี่ยน: ย่อเล็กสุด
เปลี่ยนสถานะแล้ว: ภาพ (5)

บันทึก สคริปต์นั้นเขียนด้วยหน้าต่างเดียวสำหรับแอปพลิเคชันในใจ เช่นเดียวกับคำถามของคุณ เพื่อบันทึกรายละเอียดเพิ่มเติม ต่อหน้าต่างการประมวลผลข้อมูลจะต้องมีการเข้ารหัสที่ซับซ้อนมากขึ้น

สคริปต์

#!/usr/bin/env python3
นำเข้า GI
gi.require_version("Gtk", "3.0")
gi.require_version("Wnck", "3.0")
จาก gi.repository นำเข้า Gtk, Wnck
นำเข้าระบบปฏิบัติการ
นำเข้าระบบ


คลาส WatchWindow:

    def __init__(ตัวเอง, wmclass):
        self.visual = ไม่มี
        self.count_visual = 0
        self.wnck_scr = Wnck.Screen.get_default()
        self.wmclass = wmคลาส
        self.logpath = os.environ["บ้าน"] + "/.windowlog.txt"
        self.run_watching()
        Gtk.main()

    def write_to_log (ตัวเอง ขึ้นบรรทัดใหม่):
        ด้วย open(self.logpath, "a+") เป็นไฟล์บันทึก:
            logfile.write (ขึ้นบรรทัดใหม่ + "\n")

    def readable_state (ตัวเอง, ย่อเล็กสุด):
        n = ""
        ถ้าไม่ย่อขนาด:
            self.count_visual = self.count_visual + 1
            n = "(" + str(self.count_visual) + ")"
        กลับ ["ย่อเล็กสุด", "ภาพ"][[จริง, เท็จ].index(ย่อเล็กสุด)] + n
    
    def logstate (ตัวเอง, หน้าต่าง, *args):
        old_state = self.visual
        new_state = window.is_minimized()
        # ลงทะเบียนเฉพาะเมื่อสถานะย่อเล็กสุดเปลี่ยนไปจริงๆ
        ถ้า old_state != new_state:
            self.visual = new_state
            ข้อความ = "เปลี่ยนสถานะแล้ว: " + บันทึก self.readable_state(self.visual) #
            พิมพ์(ข้อความ)
            self.write_to_log (ข้อความ)

    def log_new(ตัวเอง หน้าจอ หน้าต่าง):
        ถ้า window.get_class_group_name().lower() == self.wmclass:
            ข้อความ = "หน้าต่างใหม่:" + window.get_name() # บันทึกใหม่
            พิมพ์(ข้อความ)
            self.write_to_log (ข้อความ)
            self.watch_window (หน้าต่าง)
            self.logstate (หน้าต่าง)

    def log_closed(ตัวเอง, หน้าจอ, หน้าต่าง):
        ถ้า window.get_class_group_name().lower() == self.wmclass:
            ชื่อ = window.get_name()
            self.visual = ไม่มี
            พิมพ์ ("ปิดหน้าต่าง:", ชื่อ) # บันทึกปิด
    
    def watch_window(ตัวเอง, หน้าต่าง, firstcall=False):
        ถ้า window.get_class_group_name().lower() == self.wmclass:
            ถ้า firstcall:
                ข้อความ = "พบหน้าต่าง:" + window.get_name()
                พิมพ์ (ข้อความ) # บันทึกโปรด
                self.write_to_log("พบหน้าต่าง:" + window.get_name())
                self.logstate (หน้าต่าง)
            window.connect("state_change", self.logstate)

    def run_watching (ตัวเอง):
        พยายาม:
            os.remove(self.logpath)
        ยกเว้น FileNotFoundError:
            ผ่าน
        self.wnck_scr.force_update()
        สำหรับ w ใน self.wnck_scr.get_windows():
            self.watch_window(w, จริง)
        self.wnck_scr.connect("เปิดหน้าต่าง", self.log_new)
        self.wnck_scr.connect("ปิดหน้าต่าง", self.log_closed)

หาเรื่อง = sys.argv[1:]
ถ้าไม่เถียง:
    พิมพ์ ("อาร์กิวเมนต์ไม่เพียงพอ! เราต้องการ wm_class เพื่อดู ... ")
อื่น:
    หน้าต่างนาฬิกา (args[0])

ติดตั้ง

  1. คัดลอกสคริปต์ลงในไฟล์ว่าง บันทึกเป็น windowlogger.py และ ทำให้มันปฏิบัติการได้

  2. ทดสอบรันในหน้าต่างเทอร์มินัล รันด้วย WM_CLASS เป็นอาร์กิวเมนต์ (ฉันคิดว่า เดสก์ท็อปโทรเลข), ดังนั้น:

    /path/to/windowlogger telegramdesktop
    
  3. ดูว่าเอาต์พุตในเทอร์มินัลปกติหรือไม่ ดูภายในไฟล์บันทึก ~/.windowlog.txt ถ้าทุกอย่างเป็นไปตามที่ควร

  4. เพิ่มลงในแอปพลิเคชันเริ่มต้นของคุณหากต้องการ

NB

คุณอาจต้องเพิ่มไลบรารีอย่างน้อยหนึ่งไลบรารี ตรวจสอบเอาต์พุตของเทอร์มินัล

หน้าต่างบันทึกกำลังทำงานอยู่?

จากความคิดเห็น ฉันเข้าใจว่าคุณพิจารณาหน้าต่างนี้ว่า "ใช้แล้ว" (เท่านั้น) หากเป็นหน้าต่างที่ใช้งานอยู่
ในกรณีนี้ เราสามารถทำให้สคริปต์ง่ายขึ้นอย่างมาก เนื่องจากเรา เท่านั้น ต้องดูที่ active_window_change สัญญาณ. หากเราบันทึกการใช้งานตามเวลาด้วย (ต่อการใช้งาน / เวลาใช้งานทั้งหมด) คุณจะได้รับข้อมูลเชิงลึกที่ชัดเจนว่าคุณใช้เวลาไปเท่าไร โดยดูจากหน้าต่างโทรเลข (ใดๆ) ไฟล์บันทึกจะมีลักษณะดังนี้:

start_time: woensdag 06 ตุลาคม 2021, 11:32:53น.
เปิดใช้งานหน้าต่าง (1)
หน้าต่างถูกซ่อนหรือปิด มีการใช้งาน: 0:00:04 ทั้งหมด: 0:00:04
เปิดใช้งานหน้าต่าง (2)
หน้าต่างถูกซ่อนหรือปิด มีการใช้งาน: 0:00:06 ทั้งหมด: 0:00:10
เปิดใช้งานหน้าต่าง (3)
หน้าต่างถูกซ่อนหรือปิด มีการใช้งาน: 0:00:12 ทั้งหมด: 0:00:22
เปิดใช้งานหน้าต่าง (4)
หน้าต่างถูกซ่อนหรือปิด มีการใช้งาน: 0:00:07 ทั้งหมด: 0:00:29

สคริปต์ในกรณีนั้น:

#!/usr/bin/env python3
นำเข้า GI
gi.require_version("Gtk", "3.0")
gi.require_version("Wnck", "3.0")
จาก gi.repository นำเข้า Gtk, Wnck
นำเข้าระบบปฏิบัติการ
นำเข้าระบบ
เวลานำเข้า
วันที่และเวลานำเข้า

คลาส WatchWindow:

    def __init__(ตัวเอง, wmclass):
        self.visual = เท็จ
        self.count_visual = 1
        self.wnck_scr = Wnck.Screen.get_default()
        self.wmclass = wmคลาส
        self.logpath = os.environ["บ้าน"] + "/.windowlog.txt"
        ตัวเอง.total_time = 0
        self.last_time = time.time()
        self.run_watching()
        Gtk.main()

    def write_to_log (ตัวเอง ขึ้นบรรทัดใหม่):
        ด้วย open(self.logpath, "a+") เป็นไฟล์บันทึก:
            logfile.write (ขึ้นบรรทัดใหม่ + "\n")

    def get_readable_time (ตัวเอง, ผ่านไป):
        ส่งคืน str (datetime.timedelta (วินาที = ผ่านไป))

    def log_active(ตัวเอง, *args):
        พยายาม:
            # active_class สามารถเป็นไม่มีได้ เช่น เมื่อเริ่มต้น
            active_class = self.wnck_scr.get_active_window().get_class_group_name()
        ยกเว้น AttributeError:
            active_class = ""
        newvisual = active_class.lower() == self.wmclass.lower()
        oldvisual = self.visual
        เคอร์ไทม์ = time.time()
        ถ้าภาพใหม่ != ภาพเก่า:
            ถ้าภาพใหม่:
                self.last_time = เวลาเคอร์เรนต์
                ข้อความ = "เปิดใช้งานหน้าต่าง (" + str(self.count_visual) + ")"
                self.count_visual = self.count_visual + 1
            อื่น:
                winactive_time = currtime - self.last_time
                self.last_time = เวลาเคอร์เรนต์
                self.total_time = self.total_time + winactive_time
                ข้อความ = "หน้าต่างถูกซ่อนหรือปิด, ทำงานอยู่: " + \
                          self.get_readable_time(รอบ(winactive_time)) +\
                          "\t" + "ผลรวม: " +\
                          self.get_readable_time(รอบ(self.total_time))
            self.write_to_log (ข้อความ)
        self.visual = ภาพใหม่

    def run_watching (ตัวเอง):
        พยายาม:
            os.remove(self.logpath)
        ยกเว้น FileNotFoundError:
            ผ่าน
        time_stamp_message = "start_time: " + time.strftime(" %A, %B %d %Y, %H:%M:%S")
        self.write_to_log (เวลา_stamp_message)
        self.wnck_scr.force_update()
        self.wnck_scr.connect("เปลี่ยนหน้าต่างที่ใช้งานอยู่", self.log_active)
        self.log_active()

หาเรื่อง = sys.argv[1:]
ถ้าไม่เถียง:
    พิมพ์ ("อาร์กิวเมนต์ไม่เพียงพอ! เราต้องการ wm_class เพื่อดู ... ")
อื่น:
    หน้าต่างนาฬิกา (args[0])

การตั้งค่าเหมือนกัน

vanadium avatar
cn flag
ตอนนี้เราต้องการสิ่งนี้บน Wayland ด้วย เพื่อที่เราจะสามารถเปลี่ยนได้ ;)
Jacob Vlijm avatar
by flag
@วาเนเดียม อิอิ
Sasha R Adler avatar
cc flag
ขอบคุณ นี่คือสิ่งที่ฉันต้องการ นอกจากนี้ ฉันได้เพิ่มสัญญาณ 'หน้าต่างที่ใช้งานอยู่เปลี่ยน' เพื่อตรวจสอบดูว่าหน้าต่างที่ใช้งานเปลี่ยนกลับไปเป็นโทรเลขหรือไม่
Sasha R Adler avatar
cc flag
@JacobVlijm แน่นอนว่านั่นจะดีมาก
Jacob Vlijm avatar
by flag
@SashaRAdler เสร็จแล้ว
Sasha R Adler avatar
cc flag
@JacobVlijm เจ๋ง ขอบคุณ

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา