<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[מדריך | הפעלת המחווה לפתיחת מגירת האפליקציות במסך הבית!]]></title><description><![CDATA[<h3><a class="anchor-offset" name="אחרי-הרבה-עבודה..."></a>אחרי הרבה עבודה...</h3>
<p dir="rtl">המדריך באדיבות קלוד סונט 5</p>
<h2><a class="anchor-offset" name="צילומי-מסך"></a>צילומי מסך:</h2>
<p dir="rtl"><img src="/assets/uploads/files/1788200976797-3385ecd8-6500-4267-b4f1-3d00e4a00ab9-image.jpeg" alt="3385ecd8-6500-4267-b4f1-3d00e4a00ab9-image.jpeg" class=" img-fluid img-markdown" width="768" height="1024" /></p>
<h2><a class="anchor-offset" name="מדריך-הוספת-מחווה-לפתיחת-מגירת-האפליקציות-ב-launcher3quickstep"></a>מדריך: הוספת מחווה לפתיחת מגירת האפליקציות ב-Launcher3QuickStep</h2>
<p dir="rtl">מדריך זה מתעד את השלבים המדויקים שביצעתי כדי לפתור בעיה נפוצה בבניות מבוססות<br />
Launcher3QuickStep (AOSP) על מכשירים עם מסך ביחס ממדים חריג (כמו Qin F21 Pro)<br />
כאשר החלקה למעלה במסך הבית לא פותחת את מגירת האפליקציות.</p>
<hr />
<h2><a class="anchor-offset" name="שורש-הבעיה"></a>שורש הבעיה</h2>
<p dir="rtl">ב-Launcher3QuickStep הסטנדרטי, המחווה של החלקה למעלה כדי לפתוח את המגירה<br />
מיושמת דרך מחלקה בשם <code>PortraitStatesTouchController</code>, שנרשמת בתוך<br />
<code>QuickstepLauncher.createTouchControllers()</code>.</p>
<p dir="rtl">הבעיה: הרישום הזה <strong>מותנה</strong> בבדיקה <code>DeviceProfile.isVerticalBarLayout()</code>.<br />
במכשירים עם יחס ממדים חריג (מסכים קטנים/כמעט-מרובעים), הפונקציה הזו מחזירה<br />
<code>true</code> בטעות — מה שגורם לקוד לעבור לענף אחר (המיועד למכשירים עם hotseat<br />
אנכי, כמו טאבלטים/מכשירים מתקפלים), שבו <code>PortraitStatesTouchController</code><br />
<strong>לא</strong> נרשם בכלל. התוצאה: אין שום דרך במגע לפתוח את המגירה.</p>
<h3><a class="anchor-offset" name="איך-לזהות-את-זה-בעצמכם-ב-apk-אחר"></a>איך לזהות את זה בעצמכם ב-APK אחר</h3>
<pre><code class="language-bash"># אחרי פירוק עם apktool:
grep -n "createTouchControllers" smali_classes2/com/android/launcher3/uioverrides/QuickstepLauncher.smali
</code></pre>
<p dir="rtl">חפשו בגוף המתודה הזו קריאה ל-<code>DeviceProfile;-&gt;isVerticalBarLayout()Z</code> — אם<br />
הענף שמוסיף <code>PortraitStatesTouchController</code> תלוי בבדיקה הזו, זו אותה בעיה.</p>
<hr />
<h2><a class="anchor-offset" name="הפתרון-שבחרתי"></a>הפתרון שבחרתי</h2>
<p dir="rtl">במקום "לתקן" את <code>isVerticalBarLayout()</code> (מסוכן — הוא משפיע על עוד המון<br />
לוגיקת מסך), יצרתי <strong>controller עצמאי חדש</strong> שמזהה בעצמו החלקה למעלה על מסך<br />
הבית ופותח את המגירה — בלי שום תלות בענף השבור. הוא נרשם <strong>תמיד</strong>, בלי תנאי,<br />
כך שהוא עובד גם אם <code>isVerticalBarLayout()</code> ממשיך "לטעות".</p>
<h3><a class="anchor-offset" name="כלים-נדרשים"></a>כלים נדרשים</h3>
<ul>
<li><a href="https://apk.shnet.app/assets/uploads/files/1722434312366-%D7%9E%D7%A0%D7%94%D7%9C-mt-%D7%9E%D7%AA%D7%95%D7%A8%D7%92%D7%9D.apk" rel="nofollow ugc">MT Manager</a></li>
</ul>
<h4><a class="anchor-offset" name="מידע-חשוב-המדריך-דורש-רוט-עם-הרשאות-כתיבה"></a>מידע חשוב: המדריך דורש רוט עם הרשאות כתיבה</h4>
<h3><a class="anchor-offset" name="שלב-1-פתיחת-ה-apk-לעריכה"></a>שלב 1 — פתיחת ה-APK לעריכה</h3>
<ol>
<li>במסך הקבצים של MT Manager, אתרו את ה-APK ולחצו עליו (לא לחיצה ארוכה) —<br />
ייפתח תפריט "פתח באמצעות".</li>
<li>בחרו <strong>הצג</strong>.</li>
<li>תיפתח תצוגת עץ שמראה את מבנה ה-APK כולל <code>classes.dex</code>,<br />
<code>classes2.dex</code> וכו', כל אחד ניתן לניווט עד רמת חבילות ה-Smali.</li>
<li>נווטו לתוך <code>classes2.dex</code> (שם נמצא כל קוד ה-launcher עצמו ברוב הבניות) →<br />
<code>com/android/launcher3/uioverrides/touchcontrollers/</code>.</li>
</ol>
<h3><a class="anchor-offset" name="שלב-2-יצירת-המחלקה-החדשה"></a>שלב 2 — יצירת המחלקה החדשה</h3>
<p dir="rtl">בתוך התיקייה <code>touchcontrollers/</code> שמצאתם, צרו קובץ Smali חדש (לחצו על הקובץ הראשון לחיצה ארוכה ובחרו "הוסף") בשם בדיוק:</p>
<pre><code>SimpleAppDrawerSwipeController.smali
</code></pre>
<pre><code class="language-smali">.class public Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;
.super Ljava/lang/Object;
.source "SimpleAppDrawerSwipeController.java"

# interfaces
.implements Lcom/android/launcher3/util/TouchController;


# instance fields
.field private mCanIntercept:Z

.field private mDownX:F

.field private mDownY:F

.field private final mLauncher:Lcom/android/launcher3/Launcher;

.field private final mSwipeSlop:F


# direct methods
.method public constructor &lt;init&gt;(Lcom/android/launcher3/Launcher;)V
    .locals 2
    .param p1, "launcher"    # Lcom/android/launcher3/Launcher;

    invoke-direct {p0}, Ljava/lang/Object;-&gt;&lt;init&gt;()V

    iput-object p1, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mLauncher:Lcom/android/launcher3/Launcher;

    invoke-static {p1}, Landroid/view/ViewConfiguration;-&gt;get(Landroid/content/Context;)Landroid/view/ViewConfiguration;

    move-result-object v0

    invoke-virtual {v0}, Landroid/view/ViewConfiguration;-&gt;getScaledTouchSlop()I

    move-result v0

    mul-int/lit8 v0, v0, 0x4

    int-to-float v0, v0

    iput v0, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mSwipeSlop:F

    return-void
.end method


# virtual methods
.method public onControllerInterceptTouchEvent(Landroid/view/MotionEvent;)Z
    .locals 6
    .param p1, "ev"    # Landroid/view/MotionEvent;

    invoke-virtual {p1}, Landroid/view/MotionEvent;-&gt;getActionMasked()I

    move-result v0

    const/4 v1, 0x0

    if-nez v0, :cond_1

    iget-object v2, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mLauncher:Lcom/android/launcher3/Launcher;

    sget-object v3, Lcom/android/launcher3/LauncherState;-&gt;NORMAL:Lcom/android/launcher3/LauncherState;

    invoke-virtual {v2, v3}, Lcom/android/launcher3/Launcher;-&gt;isInState(Lcom/android/launcher3/statemanager/BaseState;)Z

    move-result v2

    iput-boolean v2, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mCanIntercept:Z

    invoke-virtual {p1}, Landroid/view/MotionEvent;-&gt;getX()F

    move-result v2

    iput v2, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mDownX:F

    invoke-virtual {p1}, Landroid/view/MotionEvent;-&gt;getY()F

    move-result v2

    iput v2, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mDownY:F

    return v1

    :cond_1
    iget-boolean v2, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mCanIntercept:Z

    if-nez v2, :cond_2

    return v1

    :cond_2
    const/4 v2, 0x2

    if-eq v0, v2, :cond_3

    return v1

    :cond_3
    invoke-virtual {p1}, Landroid/view/MotionEvent;-&gt;getPointerCount()I

    move-result v2

    const/4 v3, 0x1

    if-eq v2, v3, :cond_4

    return v1

    :cond_4
    iget v2, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mDownY:F

    invoke-virtual {p1}, Landroid/view/MotionEvent;-&gt;getY()F

    move-result v4

    sub-float/2addr v2, v4

    invoke-virtual {p1}, Landroid/view/MotionEvent;-&gt;getX()F

    move-result v4

    iget v5, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mDownX:F

    sub-float/2addr v4, v5

    invoke-static {v4}, Ljava/lang/Math;-&gt;abs(F)F

    move-result v4

    iget v5, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mSwipeSlop:F

    cmpl-float v5, v2, v5

    if-lez v5, :cond_5

    cmpl-float v5, v2, v4

    if-lez v5, :cond_5

    iget-object v5, p0, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;mLauncher:Lcom/android/launcher3/Launcher;

    invoke-virtual {v5}, Lcom/android/launcher3/Launcher;-&gt;getStateManager()Lcom/android/launcher3/statemanager/StateManager;

    move-result-object v5

    sget-object v0, Lcom/android/launcher3/LauncherState;-&gt;ALL_APPS:Lcom/android/launcher3/LauncherState;

    invoke-virtual {v5, v0}, Lcom/android/launcher3/statemanager/StateManager;-&gt;goToState(Lcom/android/launcher3/statemanager/BaseState;)V

    const/4 v0, 0x1

    return v0

    :cond_5
    return v1
.end method

.method public onControllerTouchEvent(Landroid/view/MotionEvent;)Z
    .locals 1
    .param p1, "ev"    # Landroid/view/MotionEvent;

    const/4 v0, 0x1

    return v0
.end method
</code></pre>
<p dir="rtl"><strong>איך זה עובד, בקצרה:</strong></p>
<ul>
<li><code>onControllerInterceptTouchEvent</code> עוקב אחרי כל מגע: ב-<code>ACTION_DOWN</code> הוא בודק<br />
שהמסך במצב <code>NORMAL</code> (מסך הבית, לא במגירה/overview כבר) ושומר את נקודת<br />
ההתחלה.</li>
<li>ב-<code>ACTION_MOVE</code>, אם התזוזה האנכית כלפי מעלה עוברת סף (4 × touch-slop של המערכת) והיא דומיננטית יותר מהתזוזה האופקית (כלומר מחווה אנכית ולא גרירה<br />
בין מסכים) — הוא קורא ל-<code>goToState(ALL_APPS)</code> ומחזיר <code>true</code>, מה שגורם<br />
ל-DragLayer "לגנוב" את המגע משאר הרכיבים.</li>
<li><code>onControllerTouchEvent</code> פשוט בולע את המשך המחווה כדי שלא יקרו תופעות לוואי<br />
בזמן שהמעבר למגירה כבר קורה.</li>
</ul>
<h3><a class="anchor-offset" name="שלב-3-רישום-ה-controller"></a>שלב 3 — רישום ה-controller</h3>
<p dir="rtl">חזרו תיקייה אחת אחורה (<code>uioverrides/</code>) ופתחו לעריכה את<br />
<code>QuickstepLauncher.smali</code>. חפשו בתוך הקובץ (יש חיפוש טקסט בעורך) את המתודה:</p>
<pre><code>.method public createTouchControllers()[Lcom/android/launcher3/util/TouchController;
</code></pre>
<p dir="rtl">בתוך המתודה הזו, מיד אחרי השורה הראשונה שמוסיפה פריט ל-<code>ArrayList</code> (זו<br />
שמוסיפה את ה-<code>DragController</code> — תזהו אותה לפי <code>getDragController()</code> ממש<br />
מעליה), הוסיפו את שלוש השורות הבאות:</p>
<pre><code class="language-smali">    invoke-virtual {v2, v3}, Ljava/util/ArrayList;-&gt;add(Ljava/lang/Object;)Z

    new-instance v3, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;

    invoke-direct {v3, p0}, Lcom/android/launcher3/uioverrides/touchcontrollers/SimpleAppDrawerSwipeController;-&gt;&lt;init&gt;(Lcom/android/launcher3/Launcher;)V

    invoke-virtual {v2, v3}, Ljava/util/ArrayList;-&gt;add(Ljava/lang/Object;)Z
</code></pre>
<p dir="rtl"><strong>חשוב לפני שאתם מדביקים:</strong> <code>v2</code> בקוד הזה הוא ה-register שמחזיק את<br />
ה-<code>ArrayList&lt;TouchController&gt;</code>, ו-<code>v3</code> הוא register ש<strong>חייב</strong> להיות פנוי<br />
לשימוש חוזר באותה נקודה — בדקו בעצמכם בקובץ שלכם (חפשו למעלה איפה <code>v3</code><br />
משמש לאחרונה, ולמטה איפה הוא משמש הבא). אם <code>v3</code> לא פנוי שם, או אם <code>.locals</code><br />
בתחילת המתודה נמוך מדי בשביל ה-register שבחרתם — MT Manager יזרוק שגיאת קימפול Smali ברגע השמירה/יציאה מהעורך, ותצטרכו לבחור register אחר ואולי<br />
להעלות את מספר ה-<code>.locals</code>.</p>
<h3><a class="anchor-offset" name="שלב-4-שמירה-וקימפול"></a>שלב 4 — שמירה וקימפול</h3>
<p dir="rtl">צאו מעורך ה-Smali (בדרך כלל כפתור "שמור" או חץ אחורה) (<strong>לא</strong> לסמן את "חתימה אוטומטית"!)<br />
— MT Manager יקמפל<br />
אוטומטית את השינויים בחזרה ל-dex ברגע הזה. אם יש שגיאת תחביר Smali היא<br />
תופיע כאן; אם לא, ה-APK בתיקייה שערכתם כבר מעודכן.</p>
<hr />
<h1><a class="anchor-offset" name="בהצלחה"></a>בהצלחה!</h1>
<p dir="rtl"><a href="/topic/330/%D7%A9%D7%99%D7%AA%D7%95%D7%A3-%D7%AA%D7%92%D7%95%D7%91%D7%95%D7%AA-%D7%9C-%D7%9E%D7%93%D7%A8%D7%99%D7%9A-%D7%94%D7%A4%D7%A2%D7%9C%D7%AA-%D7%94%D7%9E%D7%97%D7%95%D7%95%D7%94-%D7%9C%D7%A4%D7%AA%D7%99%D7%97%D7%AA-%D7%9E%D7%92%D7%99%D7%A8%D7%AA-%D7%94%D7%90%D7%A4%D7%9C%D7%99%D7%A7%D7%A6%D7%99%D7%95%D7%AA-%D7%91%D7%9E%D7%A1%D7%9A-%D7%94%D7%91%D7%99%D7%AA">לתגובות</a></p>
]]></description><link>https://21f4c8pf.uks1.devtunnels.ms:7777/topic/331/מדריך-הפעלת-המחווה-לפתיחת-מגירת-האפליקציות-במסך-הבית</link><generator>RSS for Node</generator><lastBuildDate>Tue, 13 Oct 2026 02:09:31 GMT</lastBuildDate><atom:link href="https://21f4c8pf.uks1.devtunnels.ms:7777/topic/331.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 01 Oct 2026 03:03:32 GMT</pubDate><ttl>60</ttl></channel></rss>