1 /* Copyright 2016 Braden Farmer
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 package com.farmerbb.taskbar.ui;
18 import android.annotation.SuppressLint;
19 import android.annotation.TargetApi;
20 import android.app.SearchManager;
21 import android.content.ActivityNotFoundException;
22 import android.content.BroadcastReceiver;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.content.SharedPreferences;
28 import android.content.pm.LauncherActivityInfo;
29 import android.content.pm.LauncherApps;
30 import android.content.pm.PackageManager;
31 import android.content.res.Configuration;
32 import android.graphics.drawable.Drawable;
33 import android.net.Uri;
34 import android.os.Build;
35 import android.os.Bundle;
36 import android.os.Handler;
37 import android.os.UserHandle;
38 import android.os.UserManager;
39 import android.provider.Settings;
40 import android.support.v4.content.LocalBroadcastManager;
41 import android.support.v7.widget.SearchView;
42 import android.util.Patterns;
43 import android.view.Gravity;
44 import android.view.LayoutInflater;
45 import android.view.MotionEvent;
46 import android.view.View;
47 import android.view.ViewGroup;
48 import android.view.WindowManager;
49 import android.view.inputmethod.EditorInfo;
50 import android.view.inputmethod.InputMethodManager;
51 import android.webkit.URLUtil;
52 import android.widget.EditText;
53 import android.widget.FrameLayout;
54 import android.widget.GridView;
55 import android.widget.LinearLayout;
56 import android.widget.ListAdapter;
57 import android.widget.TextView;
59 import com.farmerbb.taskbar.R;
60 import com.farmerbb.taskbar.activity.InvisibleActivity;
61 import com.farmerbb.taskbar.activity.InvisibleActivityAlt;
62 import com.farmerbb.taskbar.activity.SecondaryHomeActivity;
63 import com.farmerbb.taskbar.adapter.StartMenuAdapter;
64 import com.farmerbb.taskbar.util.AppEntry;
65 import com.farmerbb.taskbar.util.Blacklist;
66 import com.farmerbb.taskbar.util.FreeformHackHelper;
67 import com.farmerbb.taskbar.util.IconCache;
68 import com.farmerbb.taskbar.util.LauncherHelper;
69 import com.farmerbb.taskbar.util.MenuHelper;
70 import com.farmerbb.taskbar.util.TopApps;
71 import com.farmerbb.taskbar.util.U;
72 import com.farmerbb.taskbar.widget.StartMenuLayout;
74 import java.text.Collator;
75 import java.util.ArrayList;
76 import java.util.Collections;
77 import java.util.Comparator;
78 import java.util.List;
80 public class StartMenuController implements UIController {
82 private Context context;
83 private StartMenuLayout layout;
84 private GridView startMenu;
85 private SearchView searchView;
86 private TextView textView;
87 private PackageManager pm;
88 private StartMenuAdapter adapter;
90 private Handler handler;
91 private Thread thread;
93 private boolean shouldShowSearchBox = false;
94 private boolean hasSubmittedQuery = false;
95 private boolean hasHardwareKeyboard = false;
97 private int layoutId = R.layout.start_menu_left;
99 private List<String> currentStartMenuIds = new ArrayList<>();
101 private View.OnClickListener ocl = view -> toggleStartMenu();
103 private BroadcastReceiver toggleReceiver = new BroadcastReceiver() {
105 public void onReceive(Context context, Intent intent) {
110 private BroadcastReceiver showSpaceReceiver = new BroadcastReceiver() {
112 public void onReceive(Context context, Intent intent) {
113 layout.findViewById(R.id.start_menu_space).setVisibility(View.VISIBLE);
117 private BroadcastReceiver hideSpaceReceiver = new BroadcastReceiver() {
119 public void onReceive(Context context, Intent intent) {
120 layout.findViewById(R.id.start_menu_space).setVisibility(View.GONE);
124 private BroadcastReceiver hideReceiver = new BroadcastReceiver() {
126 public void onReceive(Context context, Intent intent) {
131 private BroadcastReceiver hideReceiverNoReset = new BroadcastReceiver() {
133 public void onReceive(Context context, Intent intent) {
134 hideStartMenu(false);
138 private BroadcastReceiver resetReceiver = new BroadcastReceiver() {
140 public void onReceive(Context context, Intent intent) {
141 startMenu.setSelection(0);
145 private Comparator<LauncherActivityInfo> comparator = (ai1, ai2) -> {
150 label1 = ai1.getLabel().toString();
151 label2 = ai2.getLabel().toString();
152 } catch (OutOfMemoryError e) {
155 label1 = ai1.getApplicationInfo().packageName;
156 label2 = ai2.getApplicationInfo().packageName;
159 return Collator.getInstance().compare(label1, label2);
162 public StartMenuController(Context context) {
163 this.context = context;
166 @TargetApi(Build.VERSION_CODES.M)
168 public void onCreateHost(UIHost host) {
169 hasHardwareKeyboard = context.getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS;
171 SharedPreferences pref = U.getSharedPreferences(context);
172 if(pref.getBoolean("taskbar_active", false) || LauncherHelper.getInstance().isOnHomeScreen()) {
173 if(U.canDrawOverlays(context, host instanceof SecondaryHomeActivity))
176 pref.edit().putBoolean("taskbar_active", false).apply();
180 } else host.terminate();
183 @SuppressLint("RtlHardcoded")
184 private void drawStartMenu(UIHost host) {
185 IconCache.getInstance(context).clearCache();
187 final SharedPreferences pref = U.getSharedPreferences(context);
188 switch(pref.getString("show_search_bar", "keyboard")) {
190 shouldShowSearchBox = true;
193 shouldShowSearchBox = hasHardwareKeyboard;
196 shouldShowSearchBox = false;
200 // Initialize layout params
201 WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
202 U.setCachedRotation(windowManager.getDefaultDisplay().getRotation());
204 final ViewParams params = new ViewParams(
205 WindowManager.LayoutParams.WRAP_CONTENT,
206 WindowManager.LayoutParams.WRAP_CONTENT,
208 shouldShowSearchBox ? 0 : WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
211 // Determine where to show the start menu on screen
212 switch(U.getTaskbarPosition(context)) {
214 layoutId = R.layout.start_menu_left;
215 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
217 case "bottom_vertical_left":
218 layoutId = R.layout.start_menu_vertical_left;
219 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
222 layoutId = R.layout.start_menu_right;
223 params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
225 case "bottom_vertical_right":
226 layoutId = R.layout.start_menu_vertical_right;
227 params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
230 layoutId = R.layout.start_menu_top_left;
231 params.gravity = Gravity.TOP | Gravity.LEFT;
233 case "top_vertical_left":
234 layoutId = R.layout.start_menu_vertical_left;
235 params.gravity = Gravity.TOP | Gravity.LEFT;
238 layoutId = R.layout.start_menu_top_right;
239 params.gravity = Gravity.TOP | Gravity.RIGHT;
241 case "top_vertical_right":
242 layoutId = R.layout.start_menu_vertical_right;
243 params.gravity = Gravity.TOP | Gravity.RIGHT;
248 layout = (StartMenuLayout) LayoutInflater.from(U.wrapContext(context)).inflate(layoutId, null);
251 startMenu = layout.findViewById(R.id.start_menu);
253 if((shouldShowSearchBox && !hasHardwareKeyboard) || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1)
254 layout.viewHandlesBackButton();
256 boolean scrollbar = pref.getBoolean("scrollbar", false);
257 startMenu.setFastScrollEnabled(scrollbar);
258 startMenu.setFastScrollAlwaysVisible(scrollbar);
259 startMenu.setScrollBarStyle(scrollbar ? View.SCROLLBARS_OUTSIDE_INSET : View.SCROLLBARS_INSIDE_OVERLAY);
261 if(pref.getBoolean("transparent_start_menu", false))
262 startMenu.setBackgroundColor(0);
264 if(U.visualFeedbackEnabled(context))
265 startMenu.setRecyclerListener(view -> view.setBackgroundColor(0));
267 searchView = layout.findViewById(R.id.search);
269 int backgroundTint = U.getBackgroundTint(context);
271 FrameLayout startMenuFrame = layout.findViewById(R.id.start_menu_frame);
272 FrameLayout searchViewLayout = layout.findViewById(R.id.search_view_layout);
273 startMenuFrame.setBackgroundColor(backgroundTint);
274 searchViewLayout.setBackgroundColor(backgroundTint);
276 if(shouldShowSearchBox) {
277 if(!hasHardwareKeyboard) searchView.setIconifiedByDefault(true);
279 searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
281 public boolean onQueryTextSubmit(String query) {
282 if(!hasSubmittedQuery) {
283 ListAdapter adapter = startMenu.getAdapter();
284 if(adapter != null) {
285 hasSubmittedQuery = true;
287 if(adapter.getCount() > 0) {
288 View view = adapter.getView(0, null, startMenu);
289 LinearLayout layout = view.findViewById(R.id.entry);
290 layout.performClick();
292 if(U.shouldCollapse(context, true))
293 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_TASKBAR"));
295 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
299 if(Patterns.WEB_URL.matcher(query).matches()) {
300 intent = new Intent(Intent.ACTION_VIEW);
301 intent.setData(Uri.parse(URLUtil.guessUrl(query)));
302 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
304 intent = new Intent(Intent.ACTION_WEB_SEARCH);
305 intent.putExtra(SearchManager.QUERY, query);
306 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
309 if(intent.resolveActivity(context.getPackageManager()) != null)
310 context.startActivity(intent);
312 Uri uri = new Uri.Builder()
314 .authority("www.google.com")
316 .appendQueryParameter("q", query)
319 intent = new Intent(Intent.ACTION_VIEW);
321 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
324 context.startActivity(intent);
325 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
334 public boolean onQueryTextChange(String newText) {
335 searchView.setIconified(false);
337 View closeButton = searchView.findViewById(R.id.search_close_btn);
338 if(closeButton != null) closeButton.setVisibility(View.GONE);
340 refreshApps(newText, false);
342 if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
343 new Handler().postDelayed(() -> {
344 EditText editText = searchView.findViewById(R.id.search_src_text);
345 if(editText != null) {
346 editText.requestFocus();
347 editText.setSelection(editText.getText().length());
356 searchView.setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
358 LinearLayout powerButton = layout.findViewById(R.id.power_button);
359 powerButton.setOnClickListener(view -> {
360 int[] location = new int[2];
361 view.getLocationOnScreen(location);
362 openContextMenu(location);
365 powerButton.setOnGenericMotionListener((view, motionEvent) -> {
366 if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
367 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
368 int[] location = new int[2];
369 view.getLocationOnScreen(location);
370 openContextMenu(location);
375 searchViewLayout.setOnClickListener(view -> searchView.setIconified(false));
377 startMenu.setOnItemClickListener((viewParent, view, position, id) -> {
380 AppEntry entry = (AppEntry) viewParent.getAdapter().getItem(position);
381 U.launchApp(context, entry, null, false, false, view);
384 if(pref.getBoolean("transparent_start_menu", false))
385 layout.findViewById(R.id.search_view_child_layout).setBackgroundColor(0);
387 searchViewLayout.setVisibility(View.GONE);
389 textView = layout.findViewById(R.id.no_apps_found);
391 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
393 lbm.unregisterReceiver(toggleReceiver);
394 lbm.unregisterReceiver(hideReceiver);
395 lbm.unregisterReceiver(hideReceiverNoReset);
396 lbm.unregisterReceiver(showSpaceReceiver);
397 lbm.unregisterReceiver(hideSpaceReceiver);
398 lbm.unregisterReceiver(resetReceiver);
400 lbm.registerReceiver(toggleReceiver, new IntentFilter("com.farmerbb.taskbar.TOGGLE_START_MENU"));
401 lbm.registerReceiver(hideReceiver, new IntentFilter("com.farmerbb.taskbar.HIDE_START_MENU"));
402 lbm.registerReceiver(hideReceiverNoReset, new IntentFilter("com.farmerbb.taskbar.HIDE_START_MENU_NO_RESET"));
403 lbm.registerReceiver(showSpaceReceiver, new IntentFilter("com.farmerbb.taskbar.SHOW_START_MENU_SPACE"));
404 lbm.registerReceiver(hideSpaceReceiver, new IntentFilter("com.farmerbb.taskbar.HIDE_START_MENU_SPACE"));
405 lbm.registerReceiver(resetReceiver, new IntentFilter("com.farmerbb.taskbar.RESET_START_MENU"));
407 handler = new Handler();
410 host.addView(layout, params);
413 private void refreshApps(boolean firstDraw) {
414 refreshApps(null, firstDraw);
417 private void refreshApps(final String query, final boolean firstDraw) {
418 if(thread != null) thread.interrupt();
420 handler = new Handler();
421 thread = new Thread(() -> {
422 if(pm == null) pm = context.getPackageManager();
424 UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
425 LauncherApps launcherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
427 final List<UserHandle> userHandles = userManager.getUserProfiles();
428 final List<LauncherActivityInfo> unfilteredList = new ArrayList<>();
430 for(UserHandle handle : userHandles) {
431 unfilteredList.addAll(launcherApps.getActivityList(null, handle));
434 final List<LauncherActivityInfo> topAppsList = new ArrayList<>();
435 final List<LauncherActivityInfo> allAppsList = new ArrayList<>();
436 final List<LauncherActivityInfo> list = new ArrayList<>();
438 TopApps topApps = TopApps.getInstance(context);
439 for(LauncherActivityInfo appInfo : unfilteredList) {
440 String userSuffix = ":" + userManager.getSerialNumberForUser(appInfo.getUser());
441 if(topApps.isTopApp(appInfo.getComponentName().flattenToString() + userSuffix)
442 || topApps.isTopApp(appInfo.getComponentName().flattenToString())
443 || topApps.isTopApp(appInfo.getName()))
444 topAppsList.add(appInfo);
447 Blacklist blacklist = Blacklist.getInstance(context);
448 for(LauncherActivityInfo appInfo : unfilteredList) {
449 String userSuffix = ":" + userManager.getSerialNumberForUser(appInfo.getUser());
450 if(!(blacklist.isBlocked(appInfo.getComponentName().flattenToString() + userSuffix)
451 || blacklist.isBlocked(appInfo.getComponentName().flattenToString())
452 || blacklist.isBlocked(appInfo.getName()))
453 && !(topApps.isTopApp(appInfo.getComponentName().flattenToString() + userSuffix)
454 || topApps.isTopApp(appInfo.getComponentName().flattenToString())
455 || topApps.isTopApp(appInfo.getName())))
456 allAppsList.add(appInfo);
459 Collections.sort(topAppsList, comparator);
460 Collections.sort(allAppsList, comparator);
462 list.addAll(topAppsList);
463 list.addAll(allAppsList);
468 List<LauncherActivityInfo> queryList;
472 queryList = new ArrayList<>();
473 for(LauncherActivityInfo appInfo : list) {
474 if(appInfo.getLabel().toString().toLowerCase().contains(query.toLowerCase()))
475 queryList.add(appInfo);
479 // Now that we've generated the list of apps,
480 // we need to determine if we need to redraw the start menu or not
481 boolean shouldRedrawStartMenu = false;
482 List<String> finalApplicationIds = new ArrayList<>();
484 if(query == null && !firstDraw) {
485 for(LauncherActivityInfo appInfo : queryList) {
486 finalApplicationIds.add(appInfo.getApplicationInfo().packageName);
489 if(finalApplicationIds.size() != currentStartMenuIds.size())
490 shouldRedrawStartMenu = true;
492 for(int i = 0; i < finalApplicationIds.size(); i++) {
493 if(!finalApplicationIds.get(i).equals(currentStartMenuIds.get(i))) {
494 shouldRedrawStartMenu = true;
499 } else shouldRedrawStartMenu = true;
501 if(shouldRedrawStartMenu) {
502 if(query == null) currentStartMenuIds = finalApplicationIds;
504 Drawable defaultIcon = pm.getDefaultActivityIcon();
506 final List<AppEntry> entries = new ArrayList<>();
507 for(LauncherActivityInfo appInfo : queryList) {
509 // Attempt to work around frequently reported OutOfMemoryErrors
514 label = appInfo.getLabel().toString();
515 icon = IconCache.getInstance(context).getIcon(context, pm, appInfo);
516 } catch (OutOfMemoryError e) {
519 label = appInfo.getApplicationInfo().packageName;
523 AppEntry newEntry = new AppEntry(
524 appInfo.getApplicationInfo().packageName,
526 appInfo.getApplicationInfo().packageName,
527 appInfo.getName()).flattenToString(),
532 newEntry.setUserId(userManager.getSerialNumberForUser(appInfo.getUser()));
533 entries.add(newEntry);
537 String queryText = searchView.getQuery().toString();
538 if(query == null && queryText.length() == 0
539 || query != null && query.equals(queryText)) {
542 SharedPreferences pref = U.getSharedPreferences(context);
543 if(pref.getString("start_menu_layout", "list").equals("grid")) {
544 startMenu.setNumColumns(3);
545 adapter = new StartMenuAdapter(context, R.layout.row_alt, entries);
547 adapter = new StartMenuAdapter(context, R.layout.row, entries);
549 startMenu.setAdapter(adapter);
552 int position = startMenu.getFirstVisiblePosition();
554 if(!firstDraw && adapter != null)
555 adapter.updateList(entries);
557 startMenu.setSelection(position);
559 if(adapter != null && adapter.getCount() > 0)
560 textView.setText(null);
561 else if(query != null)
562 textView.setText(context.getString(Patterns.WEB_URL.matcher(query).matches() ? R.string.press_enter_alt : R.string.press_enter));
564 textView.setText(context.getString(R.string.nothing_to_see_here));
573 private void toggleStartMenu() {
574 if(layout.getVisibility() == View.GONE)
580 @TargetApi(Build.VERSION_CODES.N)
581 private void showStartMenu() {
582 if(layout.getVisibility() == View.GONE) {
583 layout.setOnClickListener(ocl);
584 layout.setVisibility(View.VISIBLE);
586 if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1 && !hasHardwareKeyboard)
589 MenuHelper.getInstance().setStartMenuOpen(true);
591 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.START_MENU_APPEARING"));
593 boolean onHomeScreen = LauncherHelper.getInstance().isOnHomeScreen();
594 boolean inFreeformMode = FreeformHackHelper.getInstance().isInFreeformWorkspace();
596 if(!U.isChromeOs(context) && (!onHomeScreen || inFreeformMode)) {
597 Class clazz = inFreeformMode && !U.hasBrokenSetLaunchBoundsApi()
598 ? InvisibleActivityAlt.class
599 : InvisibleActivity.class;
601 Intent intent = new Intent(context, clazz);
602 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
603 intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
606 if(clazz.equals(InvisibleActivity.class))
607 U.startActivityLowerRight(context, intent);
608 else if(clazz.equals(InvisibleActivityAlt.class))
609 U.startActivityMaximized(context, intent);
611 context.startActivity(intent);
614 EditText editText = searchView.findViewById(R.id.search_src_text);
615 if(searchView.getVisibility() == View.VISIBLE) {
616 if(hasHardwareKeyboard) {
617 searchView.setIconifiedByDefault(true);
620 editText.setShowSoftInputOnFocus(false);
622 searchView.requestFocus();
627 new Handler().postDelayed(() -> {
628 if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1 || hasHardwareKeyboard)
631 if(hasHardwareKeyboard) {
632 searchView.setIconifiedByDefault(false);
634 editText.setShowSoftInputOnFocus(true);
636 searchView.requestFocus();
639 searchView.setOnQueryTextFocusChangeListener((view, b) -> {
640 if(!hasHardwareKeyboard) {
641 ViewGroup.LayoutParams params1 = startMenu.getLayoutParams();
642 params1.height = context.getResources().getDimensionPixelSize(
643 b && !isSecondScreenDisablingKeyboard()
644 ? R.dimen.start_menu_height_half
645 : R.dimen.start_menu_height);
646 startMenu.setLayoutParams(params1);
650 if(hasHardwareKeyboard && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)
651 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
653 InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
654 imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
659 InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
660 imm.hideSoftInputFromWindow(layout.getWindowToken(), 0);
665 private void hideStartMenu(boolean shouldReset) {
666 if(layout.getVisibility() == View.VISIBLE) {
667 layout.setOnClickListener(null);
670 MenuHelper.getInstance().setStartMenuOpen(false);
672 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.START_MENU_DISAPPEARING"));
674 layout.postDelayed(() -> {
675 layout.setVisibility(View.GONE);
677 if(!hasHardwareKeyboard)
678 searchView.setQuery(null, false);
680 searchView.setIconified(true);
681 searchView.setOnQueryTextFocusChangeListener(null);
682 hasSubmittedQuery = false;
685 startMenu.smoothScrollBy(0, 0);
686 startMenu.setSelection(0);
689 InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
690 imm.hideSoftInputFromWindow(layout.getWindowToken(), 0);
696 public void onDestroyHost(UIHost host) {
699 host.removeView(layout);
700 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
702 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
704 lbm.unregisterReceiver(toggleReceiver);
705 lbm.unregisterReceiver(hideReceiver);
706 lbm.unregisterReceiver(hideReceiverNoReset);
707 lbm.unregisterReceiver(showSpaceReceiver);
708 lbm.unregisterReceiver(hideSpaceReceiver);
709 lbm.unregisterReceiver(resetReceiver);
711 lbm.sendBroadcast(new Intent("com.farmerbb.taskbar.START_MENU_DISAPPEARING"));
714 @TargetApi(Build.VERSION_CODES.M)
716 public void onRecreateHost(UIHost host) {
719 host.removeView(layout);
720 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
722 if(U.canDrawOverlays(context, host instanceof SecondaryHomeActivity))
725 SharedPreferences pref = U.getSharedPreferences(context);
726 pref.edit().putBoolean("taskbar_active", false).apply();
733 private void openContextMenu(final int[] location) {
734 LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU_NO_RESET"));
736 Bundle args = new Bundle();
737 args.putBoolean("launched_from_start_menu", true);
738 args.putBoolean("is_overflow_menu", true);
739 args.putInt("x", location[0]);
740 args.putInt("y", location[1]);
742 new Handler().postDelayed(() -> U.startContextMenuActivity(context, args), shouldDelay() ? 100 : 0);
745 private boolean shouldDelay() {
746 SharedPreferences pref = U.getSharedPreferences(context);
747 return U.hasFreeformSupport(context)
748 && pref.getBoolean("freeform_hack", false)
749 && !FreeformHackHelper.getInstance().isFreeformHackActive();
752 private boolean isSecondScreenDisablingKeyboard() {
753 return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD)
754 .startsWith("com.farmerbb.secondscreen");